使用setExtendedAccessToken()获取长期访问令牌将返回短期令牌

use*_*755 8 php facebook-php-sdk

我尝试使用扩展的长期访问令牌

$facebook->setExtendedAccessToken();
$access_token = $facebook->getAccessToken();
Run Code Online (Sandbox Code Playgroud)

查看SDK后,我发现setExtendedAccessToken()函数正在设置长期访问令牌

protected static $kSupportedKeys =
array('state', 'code', 'access_token', 'user_id');
Run Code Online (Sandbox Code Playgroud)

$this->setPersistentData(
  'access_token', $response_params['access_token']
);
Run Code Online (Sandbox Code Playgroud)

和getAccessToken()从中返回短期访问令牌

protected $accessToken
Run Code Online (Sandbox Code Playgroud)

那么setExtendedAccessToken()的目的是什么,因为它不会返回任何内容?

小智 12

@Julian.非常感谢你在这里的灵感.我能够在不改变任何核心FB api文件的情况下完成这项工作.

发生的是,setExtendedAccessToken调用发送的值setPersistentData然后通过它发送到会话constructSessionVariableName.

因此,如果我们将其从会话中删除,然后将其设置为facebook对象,那么我们都已设置好了.

这是我的代码:

// ask for the extended token and get it from session ...
$facebook->setExtendedAccessToken();
$access_token = $_SESSION["fb_".FB_APP_ID."_access_token"];
// now set it into the facebook object ....
$facebook->setAccessToken($access_token);
// now our fb object will use the new token as usual ...
$accessToken = $facebook->getAccessToken();
Run Code Online (Sandbox Code Playgroud)


Jul*_*Lam 5

经过进一步的尝试base_facebook.php,我发现了以下内容:

  • setExtendedAccessToken();将交换短期访问令牌,Facebook 返回适当的扩展访问令牌.
  • setExtendedAccessToken();将其保存在持久性数据缓存中,但这并不意味着getAccessToken();可以访问它,因为getAccessToken();不会查询持久性缓存.此外,该类似乎将持久数据视为"故障安全",并且仅在检索数据的所有其他尝试都失败时(即,在检查signed_request和解析之后code)才使用它.
  • 在我们的例子中,返回的访问令牌setExtendedAccessToken();是最新的访问令牌,所以我入侵了一个修复程序.在底部添加以下行setExtendedAccessToken();

    // Also set the publically accessible access token value to this new extended token

    $this->accessToken = $response_params['access_token'];

  • 警告:尽管我们现在拥有新的扩展访问令牌,但后续查询Facebook以检索访问令牌(例如,在页面刷新之后)将返回相同的旧的短期访问令牌.*捂脸*

  • 即使在用户注销(从而导致短期令牌过期)并重新登录之后,Facebook也将再次返回一个短期访问令牌.
  • 但是,即使是这种情况,setExtendedAccessToken();也会返回先前检索的相同扩展访问令牌.此令牌仍可用于查询用户信息.

所以,这看起来像Facebook的bug,就像我讨厌说的那样.我们可以通过上面详述的hack来解决它,并且任何后续的获取访问令牌的调用都将返回一个短暂的访问令牌,可以一次又一次地为同一个扩展访问令牌进行交换.


原始答案

根据这个答案,新的访问令牌保存在持久数据中(正如您在问题中指出的那样),并且可以通过访问$facebook->getAccessToken();.

两个相关说明:

  • 该页面还提到,当短期访问令牌被交换为扩展访问令牌时,令牌本身可能会或可能不会更改,尽管到期时间应该已更新以反映更长的到期时间.也许当你打电话时$facebook->getAccessToken();,你只是得到了相同的令牌,但它的到期时间已经改变了?
  • 每个用户交换一个短期访问令牌的呼叫只能每天一次.我不知道为什么会这样,而且我不知道如果用户决定取消授权您的应用并重新授权,是否重置此计数器.

来自Facebook文档:

当用户使用现有的,有效的,短期用户access_token访问您的站点时,您可以选择延长该访问令牌的到期时间.我们的平台每天只会延长一次到期时间,因此即使用户每天多次撤销您的网站,该令牌也会在首次请求时延长.(强调我的)

我相信情况就是这样,因为草率的程序员会$facebook->setExtendedAccessToken();尽可能地调用每个可能的机会,希望始终检索扩展的访问令牌.(而不是首选行为,$facebook->setExtendedAccessToken();如果您当前拥有的是一个短期访问令牌,那么它只会调用- 但除非您保存了过期日期,否则您甚至会告诉它本身不是那样的可靠...!)

我的假设是,如果用户取消授权应用程序,或者令牌无效,则限制将重置,并且您可以在传入短期访问令牌时再次检索扩展访问令牌.但是,这需要进一步测试,所以请带上这一段.