Setting PHP session on index page for XSRF check

泪湿孤枕 提交于 2019-12-12 13:21:15

问题


I have run in to the following problem regarding XSRF tokens.

Client: AngularJS Server: PHP

When the index.php is hit, PHP generates an XSRF token and saves it in a session. A cookie is set with same value.

AngularJS reads the cookie and stores the value.

On subsequent POSTS, the XSRF token is sent as a header, and the idea is to compare the stored session token to the sent header.

Everything seems fine, no problems whatsoever.

BUT: the issue is, that PHP cannot read the session registered in index.php, because technically there have been no page reloads! If I hit F5 and reloads everything , the session is read nicely.

How can I set the XSRF Session token on index.php and have it available for subsequent ajax requests from the client?? I'm pulling out my hair on this one... appreciate feedback.

UPDATE

After changing the session identifier name, everything suddenly worked!

In index.php:

// Create token and set session
session_start();
$token = hash('sha256', uniqid(mt_rand(), true));
$_SESSION['XSRF']=$token; 

Later, also in index.php:

/* Give token to Angular client */
<script>
angular.module("app").constant("CSRF_TOKEN", '<?=$_SESSION['XSRF'];?>'); 
</script>

Note that I'm not using a cookie, instead I set a constant which is then made available to the .run method in Angular:

in Angular:

angular.module('app').run(['CSRF_TOKEN','$http',function(CSRF_TOKEN,$http) {

   $http.defaults.headers.common['CSRF_TOKEN'] = CSRF_TOKEN;

All requests to the server are routed to one common php file. The file checks if the header is set, and compares the two tokens:

// 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;
   }
}

回答1:


This is what I'm doing in my PHP/AngularJS projects:

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']);
}

any script called by AngularJS $http:

(AngluarJS uses the value of the cookie XSRF-TOKEN and will send it in every request as X-XSRF-TOKEN custom header, so we need to compare this value to the value stored in the 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");

Feedback welcome as I don't know exactly if this is enough XSRF protection.



来源:https://stackoverflow.com/questions/20196737/setting-php-session-on-index-page-for-xsrf-check

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!