我遇到了以下有关 XSRF 令牌的问题。
客户端:AngularJS
服务器:PHP
当index.php被点击时,PHP生成一个XSRF令牌并将其保存在会话中。
cookie 设置为相同的值。
AngularJS 读取 cookie 并存储值。
在后续的 POSTS 中,XSRF 令牌作为标头发送,其想法是将存储的会话令牌与发送的标头进行比较。
一切看起来都很好,没有任何问题。
但是:问题是,PHP 无法读取在index.php 中注册的会话,因为从技术上讲,没有页面重新加载!如果我按 F5 并重新加载所有内容,会话就会很好地读取。
如何在index.php 上设置XSRF 会话令牌并使其可用于客户端的后续ajax 请求?我正在为此抓狂……感谢反馈。
UPDATE
更改会话标识符名称后,一切突然正常了!
在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.module('app').run(['CSRF_TOKEN','$http',function(CSRF_TOKEN,$http) {
$http.defaults.headers.common['CSRF_TOKEN'] = CSRF_TOKEN;
对服务器的所有请求都会路由到一个公共 php 文件。该文件检查是否设置了标头,并比较两个标记:
// 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;
}
}