简体   繁体   English

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

[英]Getting long-lived access token with setExtendedAccessToken() returns short lived token

I try to get extended long-lived access token with 我尝试使用扩展的长期访问令牌

$facebook->setExtendedAccessToken();
$access_token = $facebook->getAccessToken();

After looking SDK I found that setExtendedAccessToken() function is setting long-lived access token in 查看SDK后,我发现setExtendedAccessToken()函数正在设置长期访问令牌

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

with

$this->setPersistentData(
  'access_token', $response_params['access_token']
);

and getAccessToken() is returning short-lived access token from 和getAccessToken()从中返回短期访问令牌

protected $accessToken

so what is the purpose of setExtendedAccessToken() since it does not return anything? 那么setExtendedAccessToken()的目的是什么,因为它不会返回任何内容?

@Julian. @Julian。 Thank you so much for the inspiration here. 非常感谢你在这里的灵感。 I was able to make this work without changing any of the core FB api files. 我能够在不改变任何核心FB api文件的情况下完成这项工作。

What happens is, the setExtendedAccessToken call sends the value to setPersistentData which then sends it into session via constructSessionVariableName . 会发生什么, setExtendedAccessToken调用将值发送到setPersistentData ,然后通过constructSessionVariableName将其发送到会话中。

So if we get it out of session, and then set it into the facebook object, we're all set. 因此,如果我们将其从会话中删除,然后将其设置为facebook对象,那么我们都已设置好了。

Here is my code: 这是我的代码:

// 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();

After further attempt to poke around base_facebook.php , I have discovered the following: 在进一步尝试围绕base_facebook.php ,我发现了以下内容:

  • setExtendedAccessToken(); will exchange a short-lived access token and Facebook will return a proper extended access token. 将交换短期访问令牌,Facebook 返回适当的扩展访问令牌。
  • setExtendedAccessToken(); saves this in the persistent data cache, but this doesn't mean getAccessToken(); 将其保存在持久数据缓存中,但这并不意味着getAccessToken(); can access it, because getAccessToken(); 可以访问它,因为getAccessToken(); doesn't query the persistent cache. 不查询持久性缓存。 Furthermore, the class seems to treat the persistent data as a "failsafe", and only uses it if all other attempts to retrieve data have failed (that is, after checking signed_request , and parsing a code ). 此外,该类似乎将持久数据视为“故障安全”,并且仅在检索数据的所有其他尝试都失败时(即,在检查signed_request和解析code )才使用它。
  • In our case, the access token returned via setExtendedAccessToken(); 在我们的例子中,通过setExtendedAccessToken();返回访问令牌setExtendedAccessToken(); is the most recent access token, so I hacked in a fix. 是最新的访问令牌,所以我修复了一个问题。 Add the following line at the bottom of setExtendedAccessToken(); setExtendedAccessToken();的底部添加以下行setExtendedAccessToken();

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

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

  • Caveat : Even though we now have the new extended access token, subsequent queries to Facebook to retrieve an access token (eg after a page refresh) will return the same old short-lived access token. 警告 :尽管我们现在拥有新的扩展访问令牌,但后续查询Facebook以检索访问令牌(例如,在页面刷新之后)将返回相同的旧的短期访问令牌。 *facepalm* *捂脸*

  • Even after the user logs out (thus causing the short-lived token to expire), and logs back in, Facebook will again return a short-lived access token. 即使在用户注销(从而导致短期令牌过期)并重新登录之后,Facebook也将再次返回一个短期访问令牌。
  • However, even though this is the case, setExtendedAccessToken(); 但是,即使是这种情况, setExtendedAccessToken(); will return the same extended access token you retrieved earlier. 将返回您之前检索到的相同扩展访问令牌。 This token is still usable to query user information. 此令牌仍可用于查询用户信息。

So, this looks like a Facebook bug, as much as I hate saying it. 所以,这看起来像Facebook的bug,就像我讨厌说的那样。 We can get around it with the hack I have detailed above, and any subsequent calls to fetch an access token will just return a short-lived access token, which can be exchanged again and again for the same extended access token. 我们可以通过上面详述的hack解决它,并且任何后续获取访问令牌的调用都将返回一个短期访问令牌,可以一次又一次地为同一个扩展访问令牌进行交换。


Original Answer 原始答案

According to this answer , the new access token is saved in the persistent data (as you have also indicated in your question), and can be accessed via $facebook->getAccessToken(); 根据这个答案 ,新的访问令牌保存在持久数据中(正如您在问题中也指出的那样),可以通过$facebook->getAccessToken(); .

Two relevant notes: 两个相关说明:

  • This page also mentions that when the short-lived access token is exchanged for an extended access token, the token itself may or may not change , although the expiry time should have updated to reflect the longer expiration. 该页面还提到,当短期访问令牌被交换为扩展访问令牌时,令牌本身可能会或可能不会更改 ,尽管到期时间应该已更新以反映更长的到期时间。 Perhaps when you call $facebook->getAccessToken(); 也许你打电话给$facebook->getAccessToken(); , you are merely getting the same token back, but its expiration has changed? ,你只是获得相同的令牌,但它的到期已经改变了?
  • The call to exchange a short-lived access token for an extended one can only be made once a day per user . 每个用户交换一个短期访问令牌的呼叫只能每天一次 I don't know why this is, and I don't know whether this counter is reset if a user decides to de-authorize your app and re-authorize. 我不知道为什么会这样,而且我不知道如果用户决定取消授权您的应用并重新授权,是否重置此计数器。

From the Facebook documentation: 来自Facebook文档:

When a user visits your site with an existing, valid, short-lived user access_token, you have the option to extend the expiration time of that access token. 当用户使用现有的,有效的,短期用户access_token访问您的站点时,您可以选择延长该访问令牌的到期时间。 Our platform will only extend the expiration time once per day , so even if a user revists your site multiple times a day, the token will be extended the first time requested. 我们的平台每天只会延长一次到期时间 ,因此即使用户每天多次撤销您的网站,该令牌也会在首次请求时延长。 (emphasis mine) (强调我的)

I believe this is the case because sloppy programmers will call $facebook->setExtendedAccessToken(); 我相信这是因为草率的程序员会调用$facebook->setExtendedAccessToken(); at every possible opportunity, in the hopes of always retrieving an extended access token. 在每一个可能的机会,希望总是检索扩展访问令牌。 (Instead of the preferred behaviour, which would be only calling $facebook->setExtendedAccessToken(); if what you currently have is a short-lived access token -- but how would you even tell unless you've saved the expiration date, which in and of itself isn't that reliable...!) (而不是首选行为,它只会调用$facebook->setExtendedAccessToken();如果您当前拥有的是一个短期访问令牌 - 但除非您保存了过期日期,否则您甚至会告诉它,本身并不可靠...!)

My assumption is that if a user de-authorizes the app, or the token otherwise invalidates, the limit will reset, and you will be able to once again retrieve an extended access token when passing in a short-lived access token. 我的假设是,如果用户取消授权应用程序,或者令牌无效,则限制将重置,并且您可以在传入短期访问令牌时再次检索扩展访问令牌。 However, this requires further testing, so please take this paragraph with a grain of salt. 但是,这需要进一步测试,所以请带上这一段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM