【问题标题】:Facebook access token server-side validation for iPhone appiPhone 应用程序的 Facebook 访问令牌服务器端验证
【发布时间】:2011-07-21 09:09:49
【问题描述】:

我正在开发基于与服务器通信的 iPhone 应用程序,我想使用 Facebook 身份验证机制。

基本上,我认为它应该像这样工作:

  1. 在我的 iPhone 应用中,用户使用他的电子邮件和密码登录 Facebook。
  2. 用户允许相关 Facebook 应用程序访问他的数据。
  3. 成功登录后,我的 iPhone 应用收到访问令牌。
  4. 在与我的服务器进一步通信时,我的 iPhone 应用程序应使用接收到的 Facebook 访问令牌(例如:在查询中)。
  5. 当我的服务器收到来自 iPhone 应用程序的带有访问令牌的查询时,它应该询问 Facebook 这个令牌是否有效(以及对谁有效),如果是,服务器应该假定用户已通过 Facebook 进行身份验证。

我的问题是:如果给定的访问令牌有效,服务器应该如何询问 Facebook?我想我应该以某种方式检查令牌是否对我的 Facebook 应用程序有效。

我已经尝试了很多 Facebook 查询来查询图形 API,但我发现了这些查询,但都没有达到我的预期。能给我举个例子吗?

【问题讨论】:

  • 除非用户在 FB 中退出应用程序,否则您可以将身份验证令牌发送到服务器(希望是 ssl)。通过graph api简单查询“/me”是成功还是失败?
  • 您将收到来自 facebook 的消息,表明您的令牌无效 :)
  • 我正在尝试做一些与您正在做的事情非常相似的事情。您从未将此问题标记为已回答,您有没有得到它的工作?
  • access_token 过期时会发生什么?我们应该要求用户再次登录吗?我想了解令牌过期后如何重新验证
  • @debianmaster 这取决于您的应用架构。如果您考虑“没有 FB 令牌 - 无法访问应用程序”的情况,那么请注销用户。否则,您可能会考虑“取消链接”逻辑,用户保持登录状态,但从 Facebook 收到的信息与他在服务器/客户端上的帐户分离。

标签: iphone facebook authentication


【解决方案1】:

您可以使用以下两步流程来验证用户访问令牌是否属于您的应用:

1) 生成应用访问令牌

(https://developers.facebook.com/docs/howtos/login/login-as-app/)

https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials

2) 调试用户访问令牌

(https://developers.facebook.com/docs/howtos/login/debugging-access-tokens/)

https://graph.facebook.com/debug_token?
input_token=INPUT_TOKEN
&access_token=ACCESS_TOKEN

其中 INPUT_TOKEN 是您要验证的用户访问令牌,而 ACCESS_TOKEN 是您从第 1 步获得的应用令牌。

调试端点基本上会转储有关令牌的所有信息,因此它会以如下方式响应:

{
    data: {
        app_id: YOUR_APP_ID,
        is_valid: true,
        metadata: {
            sso: "iphone-safari"
        },
        application: YOUR_APP_NAMESPACE,
        user_id: USER_ID,
        issued_at: 1366236791,
        expires_at: 1371420791,
        scopes: [ ]
    }
}

如果该令牌不是来自“您的应用”,那么它将返回错误响应。

【讨论】:

  • According to Facebook,这是检查令牌的正确方法。但是,第一部分是可选的,因为您可以使用您的应用程序 ID 和密码而不是管理员或应用程序令牌。
  • @BrandonZacharie 不知道你是怎么做到的,我只是尝试了应用程序 ID 和密码,并给了我“需要输入令牌参数”的错误
  • @JohnnyZ 需要输入令牌。访问令牌是灵活性所在。
  • @BrandonZacharie 你是对的,我对输入和访问令牌感到困惑。要使用应用程序 ID 和机密,我将其作为参数传入,管道作为分隔符:&access_token=APP_ID|APP_SECRET
【解决方案2】:

更新:这个答案似乎不安全,因为它不验证令牌 首先属于您的应用程序,请参阅 cmets,原始答案为 如下:

我假设您已经拥有访问令牌。在这种情况下,验证访问令牌的最简单方法是发出以下请求

https://graph.facebook.com/me?fields=id&access_token=@accesstoken

这里将@accesstoken 替换为您拥有的访问令牌。我将分解网址并逐一解释。

我们在这里发出一个图形 api 请求,它将以 JSON 字符串形式返回访问令牌所有者的 Facebook 用户 ID。关键字“我”代表当前登录的用户或访问令牌的所有者。对于这个请求,访问令牌是一个强制参数。

如果提供的访问令牌无效或过期,Facebook 只会返回某种错误消息。

对于有效的访问令牌,结果会以某种方式看起来像这样

{
   "id": "ID_VALUE"
}

【讨论】:

  • 如果该用户提供了属于不同应用的 access_token,该请求不会成功吗?
  • 可以使用任何有效的用户访问令牌(无论它属于哪个应用程序)
  • @Xiquid 这篇文章不是问题的解决方案,因为它无法验证访问令牌是否属于您的应用程序。
  • 我不明白为什么这个答案得票最多!这显然不是正确的解决方案。实际上,正确的做法是“螃蟹塞巴斯蒂安”所建议的。 debug_token 端点用于查询令牌本身的信息,这样您就可以验证令牌是否属于特定应用 ID 的特定用户 ID!
  • 是的,这个答案不正确。如果您以这种方式验证访问令牌,则有人可以从其他应用程序获取访问令牌并使用它与您的应用程序进行身份验证。
【解决方案3】:

另一种解决方案是使用https://graph.facebook.com/app/?access_token=[user_access_token],如Get application id from user access token (or verify the source application for a token) 所述。

这似乎是一个未记录的功能,但返回的 JSON 包含为其生成令牌的应用程序的 ID。如果令牌不适用于您的应用,则返回 400。

【讨论】:

  • 如何获取其他 Facebook 业务的评分。为此我需要做什么?
【解决方案4】:

在 facebook (2.2) 的最新版本中,您可以这样做:

https://developers.facebook.com/docs/graph-api/reference/v2.2/debug_token

样本输出:

{
    "data": {
        "app_id": "THE APP ID", 
        "application": "APP NAME", 
        "expires_at": 1427245200, 
        "is_valid": true, 
        "scopes": [
        "public_profile", 
        "basic_info", 
        "read_stream", 
        "email", 
        "publish_actions", 
        "read_friendlists", 
        "user_birthday", 
        "user_hometown", 
        "user_location", 
        "user_likes", 
        "user_photos", 
        "user_videos", 
        "user_friends", 
        "user_posts"
        ], 
        "user_id": "THE USER ID"
    }
}

【讨论】:

【解决方案5】:
private function facebookRequestMe($access_token)
{
    include_once "facebook.php";

    $facebook = new Facebook(array(
        "appId" => "your_application_id",
        "secret" => "your_application_secret"
    ));
    $facebook->setAccessToken($access_token);
    return $facebook->api("/me", "GET");
}

您可以从GitHub 下载 Facebook SDK for PHP。

【讨论】:

    【解决方案6】:

    如果用户向您传递了他们声称属于他们的 Facebook UID,并且您想检查它是否合法,这是一个 Python 函数,将根据他们的访问令牌验证它(Robin Jome 答案的实现):

    def verify_facebook_id(id, access_token):
        import requests
        import simplejson
        params = {'fields': 'id', 'access_token': access_token}
        text = requests.get("https://graph.facebook.com/me", params=params).text
        json = simplejson.loads(text)
        response_id = json["id"]
        return response_id == id
    

    【讨论】:

    • 不幸的是,这并不能验证令牌是“为您的应用程序”生成的......
    【解决方案7】:

    这是仅使用一个请求验证用户令牌的唯一安全方法:

    https://graph.facebook.com/debug_token?input_token={token-to-inspect}&access_token={app_id}|{app_secret}
    

    注意符号“|”在上面的 URL 中没有用作 OR 而是用作分隔符,并且必须在填写其他字段后出现。

    响应将是如下所示的 JSON:

    {
        data: {
            app_id: {app_id},
            application: {app_name},
            expires_at: {some_number},
            is_valid: {true|false}
            scopes: {array_of_permissions},
            user_id: {user_id}
        }
    }
    

    参考:https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens (以上方法在本节底部提到)

    【讨论】:

    【解决方案8】:

    除了访问令牌,Facebook 还发送一个“expires_in”参数,它是一个偏移值。使用它来计算访问令牌何时作为 NSDate 过期。然后,当您需要执行请求时,将当前日期与到期日期进行比较。

    同时尝试检查 Facebook 发回的状态代码和响应字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 2013-10-28
      • 2018-01-09
      • 2017-12-28
      相关资源
      最近更新 更多