iPhone应用程序的Facebook访问令牌服务器端验证


112

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

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

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

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

我已经尝试了许多Facebook查询来绘制API图,但我发现没有任何效果。能给我一些例子吗?


5
除非用户已退出FB中的应用程序,否则您只需将auth令牌发送到服务器即可(希望通过SSL)。通过图形API的“ / me”简单查询是成功还是失败?
2011年

您会收到来自Facebook的回复,称您的令牌无效:)
Jean-Luc Godard

1
我正在尝试做与您正在做的事情非常相似的事情。您从来没有将这个问题标记为已回答,您曾经尝试过吗?
tempy 2011年

当access_token过期时会发生什么?我们应该要求用户再次登录吗?我想了解令牌过期后如何再次重新验证
debianmaster 2015年

@debianmaster它取决于您的应用程序体系结构。如果考虑“没有FB令牌-无法访问该应用程序”的情况,则请注销用户。否则,您可能会考虑“取消链接”逻辑,即用户保持登录状态,但从Facebook收到的信息与他在服务器/客户端上的帐户分离。
Yevhen Dubinin

Answers:


115

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

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: [ ]
    }
}

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


13
根据Facebook的说法,这是检查令牌的正确方法。但是,第一部分是可选的,因为您可以使用应用程序ID和密码来代替管理员或应用程序令牌。
布兰登·扎哈里

@BrandonZacharie没有看到您如何执行此操作,我只是尝试使用应用程序ID和密码,并给我“ input_token参数必需”的错误
Johnny Z

@JohnnyZ输入令牌是必需的。访问令牌是灵活性所在。
Brandon Zacharie 2014年

8
@BrandonZacharie没错,我的输入和访问令牌感到困惑。要使用应用程序ID和密码,我将其作为参数使用管道作为分隔符:&access_token = APP_ID | APP_SECRET
Johnny Z


115

更新:此答案似乎不安全,因为它不会首先验证令牌是否属于您的应用程序,请参阅注释,原始答案如下:

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

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

在这里,将@accesstoken替换为您拥有的访问令牌。我将分解URL并解释每个URL。

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

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

对于有效的访问令牌,结果将以某种方式如下所示

{
   "id": "ID_VALUE"
}

14
如果该用户提供了一个属于另一个应用程序的access_token,该请求是否会成功?
尤里·涅姆佐夫

2
可以使用任何有效的用户访问令牌(无论它属于哪个应用程序)
Robin

12
@Xiquid这篇文章不是解决问题的方法,因为它不验证访问令牌是否属于您的应用程序。
Kolyunya 2014年

12
我不明白为什么这个答案得票最多!显然,这不是正确的解决方案。实际上,正确的方法是“塞巴斯蒂安螃蟹”的建议。debug_token端点用于查询有关令牌本身的信息,通过这种方式,您可以验证令牌属于特定应用程序ID的特定用户ID!
Alex Ntousias

4
是的,这个答案不正确。如果您以这种方式验证访问令牌,则某人可以从其他应用程序获取访问令牌,并使用它来对您的身份验证。
乔纳森(Jonathan)

11

https://graph.facebook.com/app/?access_token=[user_access_token]从用户访问令牌中获取应用程序ID所述,另一种解决方案是使用(或验证源应用程序中的令牌)

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


我如何获得其他Facebook业务的评分。我需要为此做什么?
Maneesh Rao

6

在最新版本的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"
    }
}

这是否意味着您必须在每个请求上都调用此fb端点?有没有更好的办法?
Jdruwe,2015年

这可行,但是需要访问令牌。访问令牌可以使用“塞巴斯蒂安螃蟹”答案生成,或者我们可以简单地使用appid | appsecret。富勒更多信息developers.facebook.com/docs/facebook-login/...
克里希南

这是一个使用示例:stackoverflow.com/a/16947027/32453
rogerdpack

2
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下载适用于PHP的Facebook SDK 。


1

如果用户已经向您传递了他们声称是他们的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

不幸的是,这并不能验证令牌是“为您的应用程序”生成的……
rogerdpack

1

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

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

请注意,符号“ |” 上述网址中的并不是用作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 (本节底部提到了上述方法)


有一个请求的另一种安全方式:stackoverflow.com/a/36555287/32453
rogerdpack

-1

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

还要尝试检查Facebook发送回的状态码和响应字符串。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.