Facebook access token server-side validation for iPhone app

I'm developing iPhone application, that is based on communication with server, and I want to use Facebook authentication mechanisms.

Basically, I think it should work like this:

  1. In my iPhone app, user logs in to Facebook, using his email and password.
  2. User allows access to his data for related Facebook application.
  3. My iPhone app receives access token, after successful log in.
  4. In further communication with my server, my iPhone application should use the received Facebook access token (for example: in queries).
  5. When my server receives some query from iPhone app, with access token, it should ask Facebook that this token is valid (and for who), and if yes, server should assume that user is authenticated with Facebook.

My question is: how the server should ask Facebook if given access token is valid? I think I should somehow check if the token is valid for my Facebook app.

I've tried many Facebook queries to graph API, that I've found, but nothing worked as I expected. Can you provide me some example?

50369 次浏览

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

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

更新: 这个答案似乎没有把握,因为它不验证令牌 首先作为属于你的应用程序,看看评论,原来的答案作为 如下:

我想你已经拿到访问令牌了。在这种情况下,验证访问令牌的最简单方法是发出以下请求

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

在这里用您的访问令牌替换@accesstoken。我将分解 URL 并逐一解释。

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

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

对于一个有效的访问令牌,其结果如下所示

{
"id": "ID_VALUE"
}

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

这似乎是一个没有文档说明的特性,但是返回 JSON,其中包含为其生成令牌的应用程序的 id。如果这个令牌不是为了你的应用程序,它会返回一个400。

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)生成 App Access 令牌

(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中获得的应用程序令牌。

The debug endpoint basically dumps all information about a token, so it'll respond with something like this:

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

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

如果一个用户传给你一个他们声称是自己的 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

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

This is the only secure method to verify user token using just one request:

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}
}
}

参考文献: < a href = “ https://developers.facebook.com/docs/facebook-login/access-tokens/# apptokens”rel = “ nofollow norefrer”> https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens (上述方法在本节的底部提到)