The case:
- We plug-in FB JS and init it with
FB.init(). This call createsfbsr_NNNNNcookie. The cookie has session-limited expiration date (until browser is closed). We callFB.init()only once in this example. After that we call the pages that don’t containFB.init()invocations so it doesn’t have a chance to renew the access_token - We perform authentication and make some server-side (PHP FB SDK) call, like
/me - Wait for 30 minutes or something until FB session expires
- Perform the
/merequest again and see “An active access token must be used to query information about the current user.”
This happens because current php sdk implementation:
public function getSignedRequest() {
if (!$this->signedRequest) {
if (isset($_REQUEST['signed_request'])) {
$this->signedRequest = $this->parseSignedRequest(
$_REQUEST['signed_request']);
} else if (isset($_COOKIE[$this->getSignedRequestCookieName()])) {
$this->signedRequest = $this->parseSignedRequest(
$_COOKIE[$this->getSignedRequestCookieName()]);
}
}
return $this->signedRequest;
}
just takes the access_token from cookies as-is and in case of exception it doesn’t clear it. So the code has no chance to return into normal workflow without manual cookie removing. Yes, if I delete the cookie – the code starts to work again (as long as there is no saved access_token and library fetches the new actual one).
So what workaround for this issue would you propose? What do you use? Do you think it is a bug?
UPD: seems like there is a possible workaround: to extend Facebook class and override the method that cleans persistent storages. For details look at discussion to the answer http://facebook.stackoverflow.com/a/8294559/251311
But I’m personally still sure that FB SDK should handle it without any additional hacks
First: I have no experience with Facebook itself, but the OAuth 2 RFC specifies a
refresh_token– consider implementing it.Second: Facebook returns an error, right? If that error occurs just unset the cookie. If that doesn’t work with your current implementation you’re doing something wrong – pretty much every Twitter library I have seen (also uses OAuth, albeit 1.0a) uses its own HTTP wrapper. Rather than giving back an URL to request you simply execute the request yourself.
Third: What if you simply set a timeout on the cookie? I’m rather sure OAuth also gives you an
expires_invalue, simply use it (do take 5 seconds off this value, because of network lag etc).