Настройка сеанса PHP на индексной странице для проверки XSRF

Я столкнулся с проблемой, связанной с токенами XSRF.

Клиент: Сервер AngularJS: PHP

Когда index.php попадает, PHP генерирует токен XSRF и сохраняет его в сеансе. Файл cookie устанавливается с одинаковым значением.

AngularJS считывает файл cookie и сохраняет значение.

При последующих POSTS токен XSRF отправляется как заголовок, и идея заключается в сравнении сохраненного токена сеанса с отправленным заголовком.

Все кажется прекрасным, никаких проблем.

НО: проблема в том, что PHP не может прочитать сеанс, зарегистрированный в index.php, потому что технически не было перезагрузок страниц! Если я удалю F5 и перезагрузим все, сеанс будет хорошо прочитан.

Как я могу установить токен сеанса XSRF на index.php и иметь его доступным для последующих запросов 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, вместо этого устанавливаю константу, которая затем становится доступной для метода .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; } } 

Related of "Настройка сеанса PHP на индексной странице для проверки XSRF"

Это то, что я делаю в своих проектах PHP / AngularJS:

index.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, поэтому нам нужно сравнить это значение со значением, хранящимся в сеансе.)

 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-защиты.