【问题标题】:FOSOAuthServerBundle - generate manually an access tokenFOSOAuthServerBundle - 手动生成访问令牌
【发布时间】:2013-08-09 20:20:31
【问题描述】:

我有一个 symfony2 网站 和一个通过 oauth using FOSOAuthServerBundle 保护的 Web 服务,可通过 iOS 应用访问。在网站上,我使用 FOSUserBundle 和 FOSFacebookBundle。

我唯一想念的是让用户有可能在 iOS 应用程序上使用 facebook 登录,并为我的 oauth 返回一个 access_token 链接到他的用户帐户,以便他可以像其他用户一样访问我的 api。

所以基本上我想将用户 facebookID 和 facebook_access_token 发送到我的网络服务,检查用户是否正确(令牌与我的应用程序匹配)并返回身份验证令牌。

问题:有没有一种简单的方法可以将“Facebook”grant_type 添加到 FOSOAuthServerBundle 中?

我知道有些人看到这些问题就这样做了:

但是他们没有解释如何,他们似乎没有使用 FOSOauthServerBundle 并且问题已经很老了。

我尝试过使用这个捆绑包: https://github.com/TheFootballSocialClub/FSCOAuth2FacebookGrantBundle

但是这个包在我之前只下载了 9 次,并不完全适合我的应用程序(例如,它认为 Facebook 用户用户名等于他的 facebookId)。所以我想我想做的是以我自己的方式重新实现同样的事情。

如果有人已经这样做了,我们可以提供任何指导,我们将不胜感激。

谢谢

【问题讨论】:

    标签: ios symfony oauth facebook-ios-sdk


    【解决方案1】:

    为此,你必须添加一个Grant Extensions,参见官方文档“添加Grant Extensions”:https://github.com/FriendsOfSymfony/FOSOAuthServerBundle/blob/master/Resources/doc/adding_grant_extensions.md

    您可以找到我的 FacebookGrantExtension 以从 FB access_token 获取令牌:

    class FacebookGrantExtension implements GrantExtensionInterface
    {
    protected $userManager = null;
    protected $facebookSdk = null;
    
    public function __construct(UserManager $userManager, \BaseFacebook $facebookSdk)
    {
        $this->userManager = $userManager;
        $this->facebookSdk = $facebookSdk;
    }
    
    /**
     * @see OAuth2\IOAuth2GrantExtension::checkGrantExtension
     */
    public function checkGrantExtension(IOAuth2Client $client, array $inputData, array $authHeaders)
    {
        if (!isset($inputData['facebook_access_token'])) {
            return false;
        }
    
        $this->facebookSdk->setAccessToken($inputData['facebook_access_token']);
        try {
            // Try to get the user with the facebook token from Open Graph
            $fbData = $this->facebookSdk->api('/me');
    
            if (empty($fbData) || !isset($fbData['id'])) {
                return false;
            }
    
            // Check if a user match in database with the facebook id
            $user = $this->userManager->findUserBy(array(
                'facebookId' => $fbData['id']
            ));
    
            // If no user found, register a new user and grant token
            if (null === $user) {
                return false;
            } 
            // Else, return the access_token for the user            
            else {
                return array(
                    'data' => $user
                );
            }
        } catch(\FacebookApiExceptionion $e) {
            return false;
        }
    }
    }
    

    还有 config.yml :

    my.oauth.facebook_extension:
        class: My\CoreBundle\Oauth\FacebookGrantExtension
        arguments:
            userManager: "@fos_user.user_manager"
            facebookSdk: "@fos_facebook.api"
        tags:
            - { name: fos_oauth_server.grant_extension, uri: 'http://grants.api.mywebsite.com/facebook_access_token' }
    

    【讨论】:

    • 哎呀,我以前没有看到你的答案。我所做的是当用户使用 Facebook 登录时在控制器中手动执行此操作,一旦我获得 facebook 令牌,我手动登录/注册用户并创建一个为用户设置的 access_token 并具有自动生成的所有属性.那么使用授权扩展有什么好处呢?谢谢
    • 使用授权扩展是做到这一点的“最佳方式”,但您的解决方案也有效,即使它有点棘手且适应性较差
    • 好的,谢谢!所以我知道无论如何我都无法避免有 2 个 api 请求(一个用于 facebook,一个用于我的令牌)。
    • 不,您无法在登录/注册过程中避免它。
    • 我现在也在使用这个授权扩展,但是我遇到了一个问题。我将它与 ember 和这种技术一起使用:github.com/simplabs/ember-simple-auth/blob/master/examples/…。这样,我的前端调用 facebook,然后重定向 url 就是我的后端。但是此时调用我的后端时,来自 facebook 的访问令牌可能是新的,这意味着通过 id 和令牌查找用户失败。你是怎么处理的?
    猜你喜欢
    • 1970-01-01
    • 2019-01-27
    • 2017-05-02
    • 2014-03-07
    • 2017-06-22
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 2015-09-27
    相关资源
    最近更新 更多