我遇到了以下关于 XSRF token 的问题。
客户端:AngularJS 服务器:PHP
当 index.php 被点击时,PHP 生成一个 XSRF token 并将其保存在 session 中。 cookie 设置为相同的值。
AngularJS 读取 cookie 并存储值。
在后续的 POST 中,XSRF token 作为 header 发送,其想法是将存储的 session token 与发送的 header 进行比较。
一切似乎都很好,没有任何问题。
但是:问题是 PHP 无法读取在 index.php 中注册的 session ,因为技术上没有页面重新加载!如果我按 F5 键并重新加载所有内容, session 会被很好地读取。
如何在 index.php 上设置 XSRF session token ,并使其可用于来自客户端的后续 ajax 请求?我在这件事上大发雷霆...感谢反馈。
更新
更改 session 标识符名称后,一切突然正常了!
在 index.php 中:
// Create token and set session
session_start();
$token = hash('sha256', uniqid(mt_rand(), true));
$_SESSION['XSRF']=$token;
稍后,也在 index.php 中:
/* Give token to Angular client */
<script>
angular.module("app").constant("CSRF_TOKEN", '<?=$_SESSION['XSRF'];?>');
</script>
请注意,我没有使用 cookie,而是设置了一个常量,然后可用于 Angular 中的 .run 方法:
在 Angular 中:
angular.module('app').run(['CSRF_TOKEN','$http',function(CSRF_TOKEN,$http) {
$http.defaults.headers.common['CSRF_TOKEN'] = CSRF_TOKEN;
所有对服务器的请求都被路由到一个通用的 php 文件。该文件检查是否设置了 header ,并比较两个标记:
// Only POST requests are checked (I don't use PUT/DELETE)
if($_SERVER['REQUEST_METHOD']=="POST"){
session_start();
$headerToken = $_SERVER['HTTP_CSRF_TOKEN'];
$sessionToken = $_SESSION['XSRF'];
if($headerToken!=$sessionToken){
header('HTTP/1.0 401 Unauthorized');
exit;
}
}
最佳答案
这就是我在我的 PHP/AngularJS 项目中所做的:
索引.php
session_start();
if (!isset($_SESSION['XSRF-TOKEN'])) {
$uniqueValues = md5($_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']); //add more/less/any "unique" values, see comments
$_SESSION['XSRF-TOKEN'] = sha1(uniqid(microtime() . $uniqueValues, true));
setcookie('XSRF-TOKEN', $_SESSION['XSRF-TOKEN']);
}
AngularJS 调用的任何脚本 $http:
(AngluarJS 使用 cookie XSRF-TOKEN 的值,并将在每个请求中将其作为 X-XSRF-TOKEN 自定义 header 发送,因此我们需要将该值与存储在 session 中的值进行比较。)
function verifyXSRF() {
/*
$headers = apache_request_headers();
$headerToken = "";
foreach ($headers as $header => $value) {
if ($header == "X-XSRF-TOKEN") {
$headerToken = $value;
break;
}
}
*/
//more efficient, see comments
$headerToken = $_SERVER['HTTP_X_XSRF_TOKEN'];
if ($headerToken != $_SESSION['XSRF-TOKEN']) return false;
return true;
}
session_start();
if (!verifyXSRF()) die("XSRF error");
欢迎反馈,因为我不确定这是否足以保护 XSRF。
关于php - 在索引页面上设置 PHP session 以进行 XSRF 检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20196737/