【发布时间】:2013-12-10 09:29:27
【问题描述】:
我遇到了以下关于 XSRF 令牌的问题。
客户端:AngularJS 服务器:PHP
当 index.php 被命中时,PHP 会生成一个 XSRF 令牌并将其保存在会话中。 cookie 设置为相同的值。
AngularJS 读取 cookie 并存储值。
在随后的 POSTS 中,XSRF 令牌作为标头发送,其想法是将存储的会话令牌与发送的标头进行比较。
一切看起来都很好,没有任何问题。
但是:问题是,PHP 无法读取在 index.php 中注册的会话,因为从技术上讲,没有页面重新加载!如果我按 F5 并重新加载所有内容,则会话会很好地读取。
如何在 index.php 上设置 XSRF 会话令牌并使其可用于来自客户端的后续 ajax 请求?我正在拔头发...感谢反馈。
更新
更改会话标识符名称后,突然一切正常!
在 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 文件。该文件检查是否设置了标头,并比较了两个标记:
// 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;
}
}
【问题讨论】:
-
您是在 $http 调用中发布到 index.php 还是服务器上的其他 php 页面?如果我理解您的问题,是 php 文件获得了一个空会话?
-
如果我理解正确...如果您希望它可用于 ajax 请求,您可以使用 PHP 生成 XSRF 令牌变量并放入 JS 代码...也许您的一些示例代码会有所帮助?
-
没有理由不这样做。在第一个请求中,您创建一个会话和一个令牌,并在您的第一个响应中返回会话 cookie。会话现在存在,所有后续请求都有一个活动会话。我们需要更多详细信息来帮助您。
-
大家好,感谢您的回复。稍后我会尝试发布一些代码,但基本上我不会发布到同一个 index.php 文件。所有 Ajax 请求都发布到同一个通用 php 页面。我正在检查会话,它只是不存在....直到页面重新加载。
-
大家好,很抱歉耽误了您的时间。它现在对我有用,但有趣的是我并没有太大变化。我更改了会话变量的名称,突然一切正常.. 很奇怪..
标签: php angularjs session csrf