我正在使用 Facebook 的服务器端用户身份验证来尝试让人们登录到我们的网站。为了防止 CSRF,Facebook 建议创建一个随机会话状态变量,将其传递给 FB,然后 FB 将其传回以比较值以确保没有安全问题。这似乎在除 Firefox 之外的所有浏览器中都能正常工作。Firefox 正在发送状态变量,但在返回站点时不会存储它。session_start() 出现在文档的顶部,因为出于安全原因,我删除了一些变量和其他代码,所以下面没有引用它。
if(empty($code)) {
$rand = md5(uniqid(rand(), TRUE)); // CSRF protection
$_SESSION['mbny_state'] = $rand;
$dialog_url = "https://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
. $_SESSION['mbny_state'] . "&scope=publish_stream,user_birthday,user_hometown,email";
header('Location: ' . $dialog_url);
}
$state = $_REQUEST['state'];
$secret_state = $_SESSION['state'];
// Check session state to prevent hacking
if($secret_state == $state) {
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
// store the access token for future requests
$_SESSION['access_token'] = $params['access_token'];
// define graph url allowing us to communicate with FB with user's account
$graph_url = "https://graph.facebook.com/me?access_token="
. $params['access_token'];
$user = json_decode(file_get_contents($graph_url));
}
else {
$error_message = 'An error has occurred. Your session ID does not match. Please exit and try again.<br /><br />' . $secret_state . ' :: ' . $state . ' :: ' . $_SESSION['test'];
}
Firefox 会显示错误消息。我在文档后面返回了 $_SESSION['state'] 的值,它即将变为 NULL。
此外,我在会话中添加了一个名为 test 的测试变量,它被 Firefox 很好地存储了。我错过了什么?
提前致谢。
编辑:似乎 Firefox 愿意在 if 语句之外存储会话变量。如果我在 if 语句之前设置 $_SESSION['myny_state'] ,它会在 FB 以 $code 返回时存储该值。这里的问题是状态肯定不匹配,因为它在每次页面调用时都会被重置,因为它在 if 语句之外。
我们说话的时候我正在掉头发。