PHP Facebook v5 从 cookie 获取会话
PHP Facebook v5 get session from cookie
我已经为我的网站设置了 Facebook 登录,除了 PHP 会话过期之外,一切正常。过期后,我刷新页面,我的网站认为用户已注销。第二次刷新页面后,它会重新登录用户。我假设这是 JavaScript 库正在做的事情。我不想依赖 JavaScript 库,因为我正在进行 Ajax 调用,如果会话仅通过 PHP 过期,它需要能够重新登录。
我一直在打印 $_COOKIE 以跟踪 Facebook cookie,我发现在会话结束后它们仍然存在:
Array
(
[fbm_1575590742733556] => base_domain=.mysite.us
[fbsr_1575590742733556] => 1OdQYsdikidaL08RnVXbEc1ZmU3OTNBcHVDONlZEVjckVPZGZSeWZwT1Z6ZTEyVWVXaXY5b1VlSUJqMFo5UnhKRnFlMUJxV0hQMmticGVDRnBPRmt5dsafdsafsdfdsafdsafasdfdsdsafdsaZXzg1T3dmS1JIdzZ1bjRUU3pKMnEyTXF6Vm5aUazS2AtDxUav3xMNz2PAPl2dyfE.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiJBUUF1ZVZ2UU01TkZtVUwtQXYyQXla1c1VURkYmtBbHJOdS04OWxYUWZRc0laUTd3T2xhX0RqRU5EMWh2MklBa21rTnpNZHpueTEFROVR4Yk5PYWVTbDFMZG5vMTJnaU1IS0ZPNEdHMXFYUmx6RzFWQ2tzQ0N1ZVZDU2lmYllfUEtaOGxpUktNNFM0RlBHa3pS1wLUxZQlhDVHhUMXFMWjVqNHBVdVZORVFvMGNaMmtSeUI0T202TzAwNDd2ZFhTYmRPOTU3N0VWZEczbUVyaUpkZVhPdHNzOGwtZl9Hc1JKayIsImlzc3VlZF9hdCI6MTQ2NjczNDMxMSwidXNlcl9pZCI6IjEwMTgzOTQ5MDI0NTQyNSJ9
)
在每次加载页面时,我都会调用函数:
public static function CheckToken()
{
// Get a token if we dont have one
if (!isset($_SESSION['fb_access_token']))
{
$helper = self::$api->getJavaScriptHelper();
try {
// Get the acess token
$accessToken = $helper->getAccessToken();
// OAuth 2.0 client handler
$oAuth2Client = FacebookProxy::$api->getOAuth2Client();
// Exchanges a short-lived access token for a long-lived one
$longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
// Store the access token
$_SESSION['fb_access_token'] = (string) $longLivedAccessToken;
}
catch(Facebook\Exceptions\FacebookResponseException $e)
{
// When Graph returns an error
$response['errors'][] = 'Graph returned an error: ' . $e->getMessage();
}
catch(Facebook\Exceptions\FacebookSDKException $e)
{
// When validation fails or other local issues
$response['errors'][] = 'Facebook SDK returned an error: ' . $e->getMessage();
}
}
// Set the default access token
if(isset($_SESSION['fb_access_token']))
{
self::$api->setDefaultAccessToken($_SESSION['fb_access_token']);
return true;
}
return false;
}
public static function SignInUser()
{
$errors = array();
if(isset($_GET['test'])) echo "CHECK TOKEN";
if(self::CheckToken() == true)
{
if(isset($_GET['test'])) ECHO "WE HAVE A TOKEN";
// Get info about the user
$fbuser = self::GetMyInfo(array("id","email","name","first_name","last_name"));
// Check if there is already a user with this info
$user = User::GetBy("id_facebook", $fbuser['id']);
if($user->isValid() == false)
{
$errors = null;
$user = User::Create($fbuser['email'], null, $errors);
// User already exists
if($user == false) {
$user = User::GetByEmail($fbuser['email']);
}
}
if($user != null)
{
$user->Set("id_facebook", $fbuser['id']);
$user->Set("first_name", $fbuser['first_name']);
$user->Set("last_name", $fbuser['last_name']);
$user->Save($errors);
}
else
{
$errors[] = "There was an error creating your account.";
}
if(count($errors) == 0)
{
if(isset($_GET['test'])) ECHO "SIGNING IN!";
$user->SignIn();
}
}
if(isset($_GET['test'])) ECHO "END TOKEN";
return $errors;
}
我认为我的问题出在 CheckToken 函数的某处。有没有办法从 Facebook 图书馆获取令牌?是否只是简单地将 $_SESSION['fb_access_token'] 重置为存储在 cookie 中的字符串?我假设 fbsr_ 之后的数字是动态创建的,那么我如何确定要加载的内容。如果有多个用户经过身份验证,他们的多个 cookie 是否可能存储在这里?
更新:
我手动尝试将会话令牌设置为存储在 cookie 中的字符串,但现在给我 facebook 异常错误:
Fatal error: Uncaught exception 'Facebook\Exceptions\FacebookServerException' with message 'Expected 1 '.' in the input between the postcard and the payload' in facebook_v5/Exceptions/FacebookResponseException.php:105 Stack trace: #0 facebook_v5/FacebookResponse.php(210): Facebook\Exceptions\FacebookResponseException::create(Object(Facebook\FacebookResponse)) #1 facebook_v5/FacebookResponse.php(255): Facebook\FacebookResponse->makeException() #2 facebook_v5/FacebookResponse.php(82): Facebook\FacebookResponse->decodeBody() #3 facebook_v5/FacebookClient.php(225): Facebook\FacebookResponse->__construct(Object(Facebook\FacebookRequest), '{"error":{"mess...', 400, Array) #4 facebook_v5/Facebook.php(504): Facebook\FacebookClient->sendRequest(Object(Fa in facebook_v5/Exceptions/FacebookResponseException.php on line 105
似乎无法通过 PHP 严格从 Facebook SDK 重新启动会话。这需要 JavaScript 库重新登录用户,因为 Facebook cookie 在 Facebook 域下。
我采用的方法是将 Facebook 登录与我自己的登录系统集成。当用户通过 Facebook 进行身份验证时,我会为他们创建一个帐户并将 Facebook 访问令牌存储在数据库中。然后我创建自己的 cookie 以自动将他们登录到他们的帐户中。如果他们回来并且他们的会话没有访问令牌,那么它可以在数据库中查找令牌。这种方式也更好,因为如果需要的话,您总是可以 运行 作为用户的 cron 作业(例如更新朋友或其他)。
我已经为我的网站设置了 Facebook 登录,除了 PHP 会话过期之外,一切正常。过期后,我刷新页面,我的网站认为用户已注销。第二次刷新页面后,它会重新登录用户。我假设这是 JavaScript 库正在做的事情。我不想依赖 JavaScript 库,因为我正在进行 Ajax 调用,如果会话仅通过 PHP 过期,它需要能够重新登录。
我一直在打印 $_COOKIE 以跟踪 Facebook cookie,我发现在会话结束后它们仍然存在:
Array
(
[fbm_1575590742733556] => base_domain=.mysite.us
[fbsr_1575590742733556] => 1OdQYsdikidaL08RnVXbEc1ZmU3OTNBcHVDONlZEVjckVPZGZSeWZwT1Z6ZTEyVWVXaXY5b1VlSUJqMFo5UnhKRnFlMUJxV0hQMmticGVDRnBPRmt5dsafdsafsdfdsafdsafasdfdsdsafdsaZXzg1T3dmS1JIdzZ1bjRUU3pKMnEyTXF6Vm5aUazS2AtDxUav3xMNz2PAPl2dyfE.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiJBUUF1ZVZ2UU01TkZtVUwtQXYyQXla1c1VURkYmtBbHJOdS04OWxYUWZRc0laUTd3T2xhX0RqRU5EMWh2MklBa21rTnpNZHpueTEFROVR4Yk5PYWVTbDFMZG5vMTJnaU1IS0ZPNEdHMXFYUmx6RzFWQ2tzQ0N1ZVZDU2lmYllfUEtaOGxpUktNNFM0RlBHa3pS1wLUxZQlhDVHhUMXFMWjVqNHBVdVZORVFvMGNaMmtSeUI0T202TzAwNDd2ZFhTYmRPOTU3N0VWZEczbUVyaUpkZVhPdHNzOGwtZl9Hc1JKayIsImlzc3VlZF9hdCI6MTQ2NjczNDMxMSwidXNlcl9pZCI6IjEwMTgzOTQ5MDI0NTQyNSJ9
)
在每次加载页面时,我都会调用函数:
public static function CheckToken()
{
// Get a token if we dont have one
if (!isset($_SESSION['fb_access_token']))
{
$helper = self::$api->getJavaScriptHelper();
try {
// Get the acess token
$accessToken = $helper->getAccessToken();
// OAuth 2.0 client handler
$oAuth2Client = FacebookProxy::$api->getOAuth2Client();
// Exchanges a short-lived access token for a long-lived one
$longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
// Store the access token
$_SESSION['fb_access_token'] = (string) $longLivedAccessToken;
}
catch(Facebook\Exceptions\FacebookResponseException $e)
{
// When Graph returns an error
$response['errors'][] = 'Graph returned an error: ' . $e->getMessage();
}
catch(Facebook\Exceptions\FacebookSDKException $e)
{
// When validation fails or other local issues
$response['errors'][] = 'Facebook SDK returned an error: ' . $e->getMessage();
}
}
// Set the default access token
if(isset($_SESSION['fb_access_token']))
{
self::$api->setDefaultAccessToken($_SESSION['fb_access_token']);
return true;
}
return false;
}
public static function SignInUser()
{
$errors = array();
if(isset($_GET['test'])) echo "CHECK TOKEN";
if(self::CheckToken() == true)
{
if(isset($_GET['test'])) ECHO "WE HAVE A TOKEN";
// Get info about the user
$fbuser = self::GetMyInfo(array("id","email","name","first_name","last_name"));
// Check if there is already a user with this info
$user = User::GetBy("id_facebook", $fbuser['id']);
if($user->isValid() == false)
{
$errors = null;
$user = User::Create($fbuser['email'], null, $errors);
// User already exists
if($user == false) {
$user = User::GetByEmail($fbuser['email']);
}
}
if($user != null)
{
$user->Set("id_facebook", $fbuser['id']);
$user->Set("first_name", $fbuser['first_name']);
$user->Set("last_name", $fbuser['last_name']);
$user->Save($errors);
}
else
{
$errors[] = "There was an error creating your account.";
}
if(count($errors) == 0)
{
if(isset($_GET['test'])) ECHO "SIGNING IN!";
$user->SignIn();
}
}
if(isset($_GET['test'])) ECHO "END TOKEN";
return $errors;
}
我认为我的问题出在 CheckToken 函数的某处。有没有办法从 Facebook 图书馆获取令牌?是否只是简单地将 $_SESSION['fb_access_token'] 重置为存储在 cookie 中的字符串?我假设 fbsr_ 之后的数字是动态创建的,那么我如何确定要加载的内容。如果有多个用户经过身份验证,他们的多个 cookie 是否可能存储在这里?
更新: 我手动尝试将会话令牌设置为存储在 cookie 中的字符串,但现在给我 facebook 异常错误:
Fatal error: Uncaught exception 'Facebook\Exceptions\FacebookServerException' with message 'Expected 1 '.' in the input between the postcard and the payload' in facebook_v5/Exceptions/FacebookResponseException.php:105 Stack trace: #0 facebook_v5/FacebookResponse.php(210): Facebook\Exceptions\FacebookResponseException::create(Object(Facebook\FacebookResponse)) #1 facebook_v5/FacebookResponse.php(255): Facebook\FacebookResponse->makeException() #2 facebook_v5/FacebookResponse.php(82): Facebook\FacebookResponse->decodeBody() #3 facebook_v5/FacebookClient.php(225): Facebook\FacebookResponse->__construct(Object(Facebook\FacebookRequest), '{"error":{"mess...', 400, Array) #4 facebook_v5/Facebook.php(504): Facebook\FacebookClient->sendRequest(Object(Fa in facebook_v5/Exceptions/FacebookResponseException.php on line 105
似乎无法通过 PHP 严格从 Facebook SDK 重新启动会话。这需要 JavaScript 库重新登录用户,因为 Facebook cookie 在 Facebook 域下。
我采用的方法是将 Facebook 登录与我自己的登录系统集成。当用户通过 Facebook 进行身份验证时,我会为他们创建一个帐户并将 Facebook 访问令牌存储在数据库中。然后我创建自己的 cookie 以自动将他们登录到他们的帐户中。如果他们回来并且他们的会话没有访问令牌,那么它可以在数据库中查找令牌。这种方式也更好,因为如果需要的话,您总是可以 运行 作为用户的 cron 作业(例如更新朋友或其他)。