Skip to content

Commit 6bc6489

Browse files
committed
Make sure we delete the Javascript cookie because otherwise we will get stuck in a bad state where PHP have a accesstoken that is not valid
1 parent 5ba36bc commit 6bc6489

File tree

1 file changed

+76
-7
lines changed

1 file changed

+76
-7
lines changed

src/base_facebook.php

+76-7
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,17 @@ protected function getSignedRequestCookieName() {
601601
return 'fbsr_'.$this->getAppId();
602602
}
603603

604+
/**
605+
* Constructs and returns the name of the coookie that potentially contain
606+
* metadata. The cookie is not set by the BaseFacebook class, but it may be
607+
* set by the JavaScript SDK.
608+
*
609+
* @return string the name of the cookie that would house metadata.
610+
*/
611+
protected function getMetadataCookieName() {
612+
return 'fbm_'.$this->getAppId();
613+
}
614+
604615
/**
605616
* Get the authorization code from the query parameters, if it exists,
606617
* and otherwise return false to signal no authorization code was
@@ -1086,7 +1097,7 @@ protected function shouldRetainParam($param) {
10861097
/**
10871098
* Analyzes the supplied result to see if it was thrown
10881099
* because the access token is no longer valid. If that is
1089-
* the case, then the persistent store is cleared.
1100+
* the case, then we destroy the session.
10901101
*
10911102
* @param $result array A record storing the error message returned
10921103
* by a failed API call.
@@ -1101,12 +1112,13 @@ protected function throwAPIException($result) {
11011112
// REST server errors are just Exceptions
11021113
case 'Exception':
11031114
$message = $e->getMessage();
1104-
if ((strpos($message, 'Error validating access token') !== false) ||
1105-
(strpos($message, 'Invalid OAuth access token') !== false)) {
1106-
$this->setAccessToken(null);
1107-
$this->user = 0;
1108-
$this->clearAllPersistentData();
1109-
}
1115+
if ((strpos($message, 'Error validating access token') !== false) ||
1116+
(strpos($message, 'Invalid OAuth access token') !== false) ||
1117+
(strpos($message, 'An active access token must be used') !== false)
1118+
) {
1119+
$this->destroySession();
1120+
}
1121+
break;
11101122
}
11111123

11121124
throw $e;
@@ -1150,6 +1162,63 @@ public function destroySession() {
11501162
$this->signedRequest = null;
11511163
$this->user = null;
11521164
$this->clearAllPersistentData();
1165+
1166+
// Javascript sets a cookie that will be used in getSignedRequest that we
1167+
// need to clear if we can
1168+
$cookie_name = $this->getSignedRequestCookieName();
1169+
if (array_key_exists($cookie_name, $_COOKIE)) {
1170+
unset($_COOKIE[$cookie_name]);
1171+
if (!headers_sent()) {
1172+
// The base domain is stored in the metadata cookie if not we fallback
1173+
// to the current hostname
1174+
$base_domain = '.'. $_SERVER['HTTP_HOST'];
1175+
1176+
$metadata = $this->getMetadataCookie();
1177+
if (array_key_exists('base_domain', $metadata) &&
1178+
!empty($metadata['base_domain'])) {
1179+
$base_domain = $metadata['base_domain'];
1180+
}
1181+
1182+
setcookie($cookie_name, '', 0, '/', $base_domain);
1183+
} else {
1184+
self::errorLog(
1185+
'There exists a cookie that we wanted to clear that we couldn\'t '.
1186+
'clear because headers was already sent. Make sure to do the first '.
1187+
'API call before outputing anything'
1188+
);
1189+
}
1190+
}
1191+
}
1192+
1193+
/**
1194+
* Parses the metadata cookie that our Javascript API set
1195+
*
1196+
* @return an array mapping key to value
1197+
*/
1198+
protected function getMetadataCookie() {
1199+
$cookie_name = $this->getMetadataCookieName();
1200+
if (!array_key_exists($cookie_name, $_COOKIE)) {
1201+
return array();
1202+
}
1203+
1204+
// The cookie value can be wrapped in "-characters so remove them
1205+
$cookie_value = trim($_COOKIE[$cookie_name], '"');
1206+
1207+
if (empty($cookie_value)) {
1208+
return array();
1209+
}
1210+
1211+
$parts = explode('&', $cookie_value);
1212+
$metadata = array();
1213+
foreach ($parts as $part) {
1214+
$pair = explode('=', $part, 2);
1215+
if (!empty($pair[0])) {
1216+
$metadata[urldecode($pair[0])] =
1217+
(count($pair) > 1) ? urldecode($pair[1]) : '';
1218+
}
1219+
}
1220+
1221+
return $metadata;
11531222
}
11541223

11551224
/**

0 commit comments

Comments
 (0)