'Trying to Authenticate / Protect Ajax Requests with Token in PHP returns empty Session Token

Im using tokens set via sessions that are sent within the header of the HTTP request from Ajax. These are then checked at the call file. The token is created with bin2hex() and random_bytes()

Then it is set as within HTML meta:

echo '<meta name="token" content="' . $_SESSION["token"] . '">';

Then Jquery grabs the token from the meta and the Ajax call will send it in the header:

        const token = $('meta[name="token"]').attr('content');
    
    $.ajax({
        type: "POST",
        url: "./includefrontend/get-to.php",
        headers: {"token": token},          
        data:'from='+val,           
        success: function(data){
            $("#index-to-select-field").html(data);
            $("#loader").hide();
        }, 
        // success: function (result) {
            // console.log(result)
        // },
    });

Now onto get-to.php which is the endpoint for the call first a check is made if a token exists in the header. If a token does exist then it is checked if it doesn’t match the one set from the session.

If either of these conditions fail, it outputs the error message and exits.

        $headers = getallheaders();
    if (isset($headers['token'])) {
        $header_token = $headers['token'];
        if ($header_token != $_SESSION['token']) {
            echo "ERROR: Tokens dont match";
            echo ' | session token: '.$_SESSION['token'];
            echo ' | header token: '.$header_token;
            echo ' | Session Print: '.Print_r ($_SESSION);
            exit;
        }
    } else {
        echo "ERROR: No token sent";
        exit;
    }

I have the following setup, but unfortunately the session token returns empty. Any idea where the problem is?

Main File:

    <?php
       session_start();      
        $token = bin2hex(random_bytes(64));
        $_SESSION['token'] = $token;    
    ?>
    <script>
        function getState(val) {
            
            $("#loader").show();

            // var token = <?php echo json_encode($token); ?>;

            const token = $('meta[name="token"]').attr('content');
            
            $.ajax({
                type: "POST",
                url: "./includefrontend/get-to.php",
                headers: {"token": token},          
                data:'from='+val,           
                success: function(data){
                    $("#index-to-select-field").html(data);
                    $("#loader").hide();
                }, 
                // success: function (result) {
                    // console.log(result)
                // },
            });
        }
    </script>

    <!DOCTYPE html>
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
            <?php echo '<meta name="token" content="' . $_SESSION["token"] . '">'; ?>       
            <link rel="stylesheet" href="css/style.css" />
        </head>
      
    <body class="home">
    ...

File called by Ajax POST url:

    <?php

       session_start();      


        // Check if bin2hex(random_bytes(64)); token matches - if not exit / stop file execution
        $headers = getallheaders();
        if (isset($headers['token'])) {
            $header_token = $headers['token'];
            if ($header_token != $_SESSION['token']) {
                echo "ERROR: Tokens dont match";
                echo ' | session token: '.$_SESSION['token'];
                echo ' | header token: '.$header_token;
                echo ' | Session Print: '.Print_r ($_SESSION);
                exit;
            }
        } else {
            echo "ERROR: No token sent";
            exit;
        }
    ?>

Response Output:

ERROR: Tokens dont match
session token:
header token: e625e60ade6072827aeea80f5f3e886a76b1b20850038fe73df15e538a538d5024429c8cd24e46a322b22aa2b30936a3dc6832e1b3a2c1e78a7c445ee7a968
Session Print: 1


Solution 1:[1]

Found the problem. It was a line of code which was commented out above session_start();. Make sure you call session_start() at the top of all the pages you wish to use the session. Hope this helps.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 evavienna