如何使用访问令牌获取Facebook用户ID

98

我有一个Facebook桌面应用程序,并且正在使用Graph API。 我可以获得访问令牌,但在此之后 - 我不知道如何获取用户的ID。

我的流程如下:

  1. 我将用户发送到具有所有必需扩展权限的https://graph.facebook.com/oauth/authorize

  2. 在我的重定向页面中,我从Facebook获取代码。

  3. 然后我使用我的API密钥执行HTTP请求到graph.facebook.com/oauth/access_token,并在响应中获取访问令牌。

从那时起,我无法获得用户ID。

如何解决这个问题?

8个回答

166

如果您想使用Graph API获取当前用户ID,则只需向以下地址发送请求:

https://graph.facebook.com/me?access_token=...

1
我尝试了上面的确切调用:只返回:{"success":true} - Paul Kenjora
5
现在不再返回ID,请使用:https://graph.facebook.com/me?fields=id&access_token=xxxxxx - M3RS
2
“access_token” 是什么?我尝试使用页面访问令牌和用户访问令牌,但是此方法返回“无效令牌”的错误响应。 - Ant
@Ant,你需要实现FaceBook登录以获取访问令牌。 - Zeeshan Ahmad Khalil
我该如何获取用户名?我正在使用nodsjs的passport-facebook。我的范围是: ['public_profile','user_gender','user_managed_groups','pages_show_list','email']在调用passport-facebook时,profile-fields为: profileFields:['id','name','email','gender','birthday','displayName','picture.type(large)']有什么想法,如何获得用户名? (仅供参考:如果个人资料是https://www.facebook.com/charels.woodson,则我想要“charels.woodson”) - Shivam Verma
curl -i -H 'Authorization: Bearer <access token>' https://graph.facebook.com/me?fields=id cc @serg 现在不能再使用查询参数。 - Ivan Black

37
最简单的方法是:
https://graph.facebook.com/me?fields=id&access_token="xxxxx"

然后你会得到仅包含用户ID的JSON响应。


2
{ "error": { "message": "(#100) 未知字段:userid。", "type": "OAuthException", "code": 100 } } - Nikolay Kuznetsov
1
@NikolayKuznetsov:抱歉,我写错了,应该是id而不是userid,我已经修改了,请再试一次。 - pashaplus
1
没问题,我已经尝试过了,所以我发表了我的先前评论。 - Nikolay Kuznetsov
2
我遇到了以下错误,我的访问令牌是有效的。{ "error": { "message": "必须使用活动访问令牌来查询有关当前用户的信息。", "type": "OAuthException", "code": 2500, "fbtrace_id": "HA0UNBRymfa" } } - Ajit Goel
什么是访问令牌,从哪里获取它? - Masroor
如何获取用户名。 我正在使用nodsjs的passport-facebook。我的范围是: ['public_profile','user_gender','user_managed_groups','pages_show_list','email']而在调用passport-facebook时,profile-fields是: profileFields:['id','name','email','gender','birthday','displayName','picture.type(large)']有任何想法如何获取用户名吗? (仅供参考:如果个人资料为https://www.facebook.com/charels.woodson,则我希望获得“charels.woodson”) - Shivam Verma

10

Facebook访问令牌看起来类似于“1249203702 | 2.h1MTNeLqcLqw __. 86400.129394400-605430316 | -WE1iH_CV-afTgyhDPc”

如果使用|拆分中间部分,您将得到“2.h1MTNeLqcLqw__.86400.129394400-605430316”

然后再次使用 - 进行拆分

最后一部分的 “605430316” 是用户ID。

以下是提取访问令牌中用户ID的C#代码:

   public long ParseUserIdFromAccessToken(string accessToken)
   {
        Contract.Requires(!string.isNullOrEmpty(accessToken);

        /*
         * access_token:
         *   1249203702|2.h1MTNeLqcLqw__.86400.129394400-605430316|-WE1iH_CV-afTgyhDPc
         *                                               |_______|
         *                                                   |
         *                                                user id
         */

        long userId = 0;

        var accessTokenParts = accessToken.Split('|');

        if (accessTokenParts.Length == 3)
        {
            var idPart = accessTokenParts[1];
            if (!string.IsNullOrEmpty(idPart))
            {
                var index = idPart.LastIndexOf('-');
                if (index >= 0)
                {
                    string id = idPart.Substring(index + 1);
                    if (!string.IsNullOrEmpty(id))
                    {
                        return id;
                    }
                }
            }
        }

        return null;
    }

警告:访问令牌的结构未经记录,可能并不总是符合上述模式。使用时需自行承担风险。

更新:由于 Facebook 的更改,从加密的访问令牌获取用户 ID 的首选方法如下:

try
{
    var fb = new FacebookClient(accessToken);
    var result = (IDictionary<string, object>)fb.Get("/me?fields=id");
    return (string)result["id"];
}
catch (FacebookOAuthException)
{
    return null;
}

5
在Facebook更新到OAuth2.0之前,这个方法运作得很完美。但是现在无法继续使用了。 - lucemia
12
我希望我之前听取了对这种方法的警告。今天,我们措手不及,因为访问令牌的格式似乎突然发生了变化。我强烈建议避免使用这种方法,而是采用被广泛接受的回答。 - Todd Menier
2
这是我见过的最有趣的答案:D - khunshan
还要注意,像这样的方法不会验证给定的用户ID - 任何人都可以拼接他们想要的ID,而这段代码会盲目地信任它。 - Matt Lyons-Wood

7
你可以在 onSuccess(LoginResult loginResult) 中使用以下代码:

loginResult.getAccessToken().getUserId();

该代码用于获取用户的访问令牌并返回其用户ID。

6

您只需要调用另一个Graph API:

https://graph.facebook.com/me?access_token={access-token}

它将提供你的电子邮件ID和用户ID(针对Facebook)。

我只从中获得provider_id和name,但我无法从Facebook获取username。例如链接,这是直接打开用户个人资料的用户名,而仅使用提供者ID则无效。 - Salman Riyaz

3

使用最新的API,这是我用于它的代码

/*params*/
NSDictionary *params = @{
                         @"access_token": [[FBSDKAccessToken currentAccessToken] tokenString],
                         @"fields": @"id"
                         };
/* make the API call */
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
                              initWithGraphPath:@"me"
                              parameters:params
                              HTTPMethod:@"GET"];

[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
                                      id result,
                                      NSError *error) {
    NSDictionary *res = result;
    //res is a dict that has the key
    NSLog([res objectForKey:@"id"]);

我明白你的想法,但它只返回令牌而不是用户ID。 - János
请注意,这个答案已经有两年的历史了。他们可能已经更改了SDK的某些部分。 - AndrewSmiley

2
在FacebookSDK v2.1中(我无法检查旧版本),我们有:
NSString *currentUserFBID = [FBSession activeSession].accessTokenData.userID;

然而,根据FacebookSDK中的注释:

@discussion 对于像iOS系统帐户这样的登录行为可能不会填充此字段。

因此,您应该检查它是否可用,然后决定是否使用它,或调用请求以获取用户ID。


0

看看这个答案,它描述了如何获取ID响应。 首先,您需要创建获取数据的方法:

const https = require('https');
getFbData = (accessToken, apiPath, callback) => {
    const options = {
        host: 'graph.facebook.com',
        port: 443,
        path: `${apiPath}access_token=${accessToken}`, // apiPath example: '/me/friends'
        method: 'GET'
    };

    let buffer = ''; // this buffer will be populated with the chunks of the data received from facebook
    const request = https.get(options, (result) => {
        result.setEncoding('utf8');
        result.on('data', (chunk) => {
            buffer += chunk;
        });

        result.on('end', () => {
            callback(buffer);
        });
    });

    request.on('error', (e) => {
        console.log(`error from facebook.getFbData: ${e.message}`)
    });

    request.end();
}

然后只需在需要时使用您的方法,就像这样:

getFbData(access_token, '/me?fields=id&', (result) => {
      console.log(result);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接