After further attempt to poke around base_facebook.php
, I have discovered the following:
setExtendedAccessToken();
will exchange a short-lived access token and Facebook will return a proper extended access token.
setExtendedAccessToken();
saves this in the persistent data cache, but this doesn't mean getAccessToken();
can access it, because 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
).
In our case, the access token returned via setExtendedAccessToken();
is the most recent access token, so I hacked in a fix. Add the following line at the bottom of 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 (e.g. after a page refresh) will return the same old short-lived access token. *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.
- However, even though this is the case,
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. 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.
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();
.
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();
, 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:
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. 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();
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...!)
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.