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

Php 使用setExtendedAccessToken()获取长期访问令牌将返回短期令牌,php,facebook-php-sdk,Php,Facebook Php Sdk,我尝试使用扩展的长寿命访问令牌 $facebook->setExtendedAccessToken(); $access_token = $facebook->getAccessToken(); 查看SDK后,我发现setExtendedAccessToken()函数正在设置中的长期访问令牌 protected static $kSupportedKeys = array('state', 'code', 'access_token', 'user_id'); 与 getAcce

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

$facebook->setExtendedAccessToken();
$access_token = $facebook->getAccessToken();
查看SDK后,我发现setExtendedAccessToken()函数正在设置中的长期访问令牌

protected static $kSupportedKeys =
array('state', 'code', 'access_token', 'user_id');

getAccessToken()正在从返回短期访问令牌

protected $accessToken

既然setExtendedAccessToken()不返回任何内容,那么它的用途是什么呢?

在进一步尝试查看
base\u facebook.php
之后,我发现了以下几点:

  • setExtendedAccessToken()
    将交换一个短期访问令牌,Facebook将返回一个适当的扩展访问令牌
  • setExtendedAccessToken()
    将其保存在持久数据缓存中,但这并不意味着
    getAccessToken()
    可以访问它,因为
    getAccessToken()不查询持久缓存。此外,该类似乎将持久数据视为“故障保护”,并且仅在所有其他检索数据的尝试都失败时(即,在检查
    签名的\u请求之后,并解析
    代码之后)才使用它
  • 在本例中,访问令牌通过
    setExtendedAccessToken()返回
    是最新的访问令牌,因此我入侵了一个修复程序。在
    setExtendedAccessToken()的底部添加以下行

    //还将公共访问令牌值设置为此新扩展令牌

    $this->accessToken=$response\u params['access\u token']

  • 注意事项:尽管我们现在有了新的扩展访问令牌,但随后对Facebook进行的检索访问令牌的查询(例如,页面刷新后)将返回相同的旧短期访问令牌*掌纹*

  • 即使在用户注销(从而导致短期令牌过期)并重新登录后,Facebook也会再次返回短期访问令牌
  • 然而,即使是这样,
    setExtendedAccessToken()
    将返回与先前检索到的相同的扩展访问令牌。此令牌仍然可用于查询用户信息
所以,这看起来像是一个Facebook bug,尽管我很讨厌这么说。我们可以通过我上面详细介绍的黑客攻击绕过它,任何后续的获取访问令牌的调用都只会返回一个短期访问令牌,可以一次又一次地交换相同的扩展访问令牌


原始答案

根据,新的访问令牌保存在持久数据中(正如您在问题中所指出的),可以通过
$facebook->getAccessToken()访问

两项相关说明:

  • 还提到,当短期访问令牌被交换为扩展访问令牌时,令牌本身可能会改变,也可能不会改变,尽管到期时间应该已经更新以反映更长的到期时间。也许当您调用
    $facebook->getAccessToken()时
    ,您只是要取回相同的令牌,但其过期时间已更改
  • 每个用户每天只能进行一次将短期访问令牌交换为扩展访问令牌的调用。我不知道这是为什么,我也不知道如果用户决定取消您的应用程序授权并重新授权,是否会重置此计数器
从Facebook文档中:

当用户使用现有的有效短期用户访问令牌访问您的站点时,您可以选择延长该访问令牌的过期时间我们的平台每天只会延长过期时间一次,因此即使用户每天多次修改您的站点,令牌也会在第一次请求时延长。(强调矿山)

我相信这是因为草率的程序员会调用
$facebook->setExtendedAccessToken()在每个可能的机会,希望总是检索扩展访问令牌。(而不是首选行为,即如果您当前拥有的是短期访问令牌,则只调用
$facebook->setExtendedAccessToken();
,但如果您没有保存过期日期,您怎么知道呢?过期日期本身并不可靠……)


我的假设是,如果用户取消对应用程序的授权,或者令牌以其他方式无效,则限制将重置,并且在传入短期访问令牌时,您将能够再次检索扩展访问令牌。然而,这需要进一步的测试,所以请对这一段持保留态度。

@Julian。非常感谢你给我的灵感。 我能够在不更改任何核心FBAPI文件的情况下完成这项工作

发生的情况是,
setExtendedAccessToken
调用将值发送到
setPersistentData
,然后该值通过
ConstructionSessionVariableName
发送到会话中

所以,如果我们将它从会话中取出,然后将它设置到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();

我也希望有人能对这个问题给出任何有用的答案。Julian H.Lam当我不使用facebook chrome时,它似乎起作用,也许他们的意思是使用使用facebook的网页,而不是fb chrome中显示的web应用。你有跨浏览器版本吗?有时不设置该会话,例如使用Mac OSX Opera
// 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();