从用户访问令牌中获取应用程序ID(或验证令牌的来源应用程序)

61

我发现了这个问题,它有一个答案,但是自那以后Facebook改变了令牌格式,现在它是这样的:

AAACEdEose0cBACgUMGMCRi9qVbqO3u7mdATQzg[more funny letters]ig8b3uss9WrhGZBYjr20rnJu263BAZDZD

简而言之,你无法从中推断出任何信息。我还发现了访问令牌调试器,如果你粘贴一个令牌进去,它会显示我正在寻找的信息,这很好,但不能帮助我以编程方式完成它。
重点是,如果有人为用户获取了一个令牌,他可以使用它来访问图形,这就是我在我的应用程序中所做的-我想确保人们转发了由我的应用程序发出的令牌,而不是其他令牌。
我的应用程序流程是:
1. 从 Facebook 获取访问令牌(没有特别之处,在这里,服务器端流程中描述的方式。 (也使用 iPhone 和 Android,并且如果我记得正确,它们具有类似的流程)
[设备] <-> [Facebook]
2. 使用该访问令牌,设备将使用令牌访问我的应用程序服务器
[设备] <-> [Jonathan的应用程序]
在我的服务器上,我将访问令牌附加到用户上,并使用它来授予该用户在我的应用程序中的权限。(使用 Facebook 连接来验证用户)
我的应用程序是安全的,访问也是经过身份验证的,与 Facebook 无关,但是!在这个流程中,我确定的一个薄弱环节是我无法确定获取的访问令牌是否为我的应用程序签名-我不喜欢它,因为我会缓存离线使用的令牌,我希望它们百分之百是我的应用程序,具有我的权限。

那么,最好的身份验证方式是什么,以确保我获得的令牌与我的应用程序相关(为了与用户关联,我使用令牌访问 /me 并查看此令牌所属的用户)。

我不需要解密令牌(我猜它是某种 AES),我只是在寻找一个端点,告诉我令牌与我的应用程序 ID 匹配。

(编辑:如果有影响的话,使用 C# SDK,但调用图形/REST 来提供该信息同样好 :))


1
很棒的问题,还有很好的答案。这对我来说也是一个缺失的环节。谢谢。 - Martin Wawrusch
请参考以下网址:https://dev59.com/jWoy5IYBdhLWcg3wYMyB。 - Vadzim
4个回答

64

1
好的,我会点赞这个回答,因为它有效,但我仍然没有在FB API文档中看到过它。它不是api_id,而是文字“app”放在URL中。响应包括一些JSON,其中包括应用程序ID(在响应中简称为“id”)。非常棒! - PapaFreud
请看下面的官方方法,而不是一些偶然有效的巫术 :) - Raimundas Sakalauskas

25

检查访问令牌的官方图形终端点如下:

GET graph.facebook.com/debug_token?
      input_token=[user_access_token]&
      access_token=[app_token_or_admin_token]

示例响应:

{
    "data": {
        "app_id": 138483919580948, 
        "application": "Social Cafe", 
        "expires_at": 1352419328, 
        "is_valid": true, 
        "issued_at": 1347235328, 
        "metadata": {
            "sso": "iphone-safari"
        }, 
        "scopes": [
            "email", 
            "publish_actions"
        ], 
        "user_id": 1207059
    }
}

app_token_or_admin_token 可以通过 Graph API 调用获得:

GET graph.facebook.com/oauth/access_token?
     client_id={app-id}
    &client_secret={app-secret}
    &grant_type=client_credentials

如果用户的user_access_token不属于生成app_token_or_admin_token的应用程序,则debug_token端点将失败。

相关Facebook文档:


我一直在尝试这个,但要么出现“未知的OAuth 2.0方法,debug_token”,要么告诉我缺少“client_id”或“redirect_uri”,如果我不包括它们。官方文档仍然包含这一步骤,有什么想法吗? - Scott Salyer

5
使用appsecret_proof是确保这一点的文档方式。
GET graph.facebook.com/v2.5/me?access_token=[TOKEN]&appsecret_proof=[PROOF]

这不仅验证了所提供的令牌是否有效,还验证了该令牌属于哪个应用程序。它还可以一次性获取用户数据。

您可以使用以下代码(来自此处)在C#中派生PROOF

public static string ComputeHmacSha256Hash(string valueToHash, string key)
{
    byte[] keyBytes = Encoding.ASCII.GetBytes(key); 
    byte[] valueBytes = Encoding.ASCII.GetBytes(valueToHash);
    byte[] tokenBytes = new HMACSHA256(keyBytes).ComputeHash(valueBytes);
    valueBytes = null;
    keyBytes = null; 

    StringBuilder token = new StringBuilder();
    foreach (byte b in tokenBytes)
    {
        token.AppendFormat("{0:x2}", b);
    }
    tokenBytes = null; 

    return token.ToString();
}

ComputeHmacSha256Hash(accessToken, appSecret);

1
确认,这是最好的方法。如果appsecret_proof为另一个应用程序生成,则会抛出错误,尽管令牌有效。此外,appsecret_proof可以附加到API的任何方法。 - user6416335
不再支持V4.0,需要使用应用访问令牌access_token - Ratul Sharker

4

为什么不使用官方的方法?以下是来自 Facebook 安全视频的请求:

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

响应: "data": { "app_id": {token-app-id}, "user_id": {token-user-id}, ... }

官方视频链接: https://www.facebook.com/FacebookforDevelopers/videos/10152795636318553/

我截了一张屏幕截图,这样就可以看到时间,并且如果您感兴趣,可以找到更多信息。

Facebook video screenshot


1
谢谢。其他人请注意:必须包括字面上的“|”字符(这不表示“或”)。https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens - Mike S
这里access_token ={app_id}|{app_secret}是错误的。 - Ratul Sharker
尝试了那么长时间,但一次都没有成功。 - uneq95

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