php - 在索引页面上设置 PHP session 以进行 XSRF 检查

标签 php angularjs session csrf

我遇到了以下关于 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/

相关文章:

php - 在 mySQL 数据库中插入 HTML 数据

javascript - 与 ng-model 和 ng-options 绑定(bind)时选择不选择

node.js - 蒙戈错误: Cannot use a session that has ended (only on 1 collection)

php - 调用mysql连接+查询或调用数据文件哪个更快?

php - 使用数据库存储 session 时的 session cookie参数

javascript - 使用 iframe 加载本地文件

javascript - Angular ng-repeat 但重复中的指令不同

ruby-on-rails-3 - AuthLogic 似乎为一个请求多次更新用户记录

php - #php - "page expire"而不是 "session expire"

javascript - OnSubmit Javascript 不覆盖提交操作