Back

Technologies:

javascriptjavascript
laravellaravel
vue.jsvue.js
phpphp
avatar
Tolerim
21 hours ago

Why does Axios obtain a fresh session ID for each request and refuse to send CSRF?

In my current project, I am developing an online store by integrating Laravel API and VueJS components. Once a user adds an item to their cart, the application sends a post request to the API, which creates a record in the "CartData" table with the session ID. It then saves the selected product to another table with a "hasMany" relationship, called "CartItems," while setting the cart ID from the CartData. The final output should resemble the following tables: CartData: | id | session_id | |----|------------| | 4 | ASDABC123 | CartItems: | id | cartdataid | productid | productdata | |----|--------------|------------|------------------------| | 1 | 4 | 2 | *data of the product in json* | However, currently, the application generates a new session ID with every "add to cart" click. Whereas, when I use the `session()->getId()` function in the blade template, it displays the same session ID every time. How can I fix this problem? Why is this happening? Am I missing anything? The "buy" method used in Vue app is as follows:

buy(item) {
    axios.post(
        'api/cart/add',
        {
            product_id: item.id,
            product_data: JSON.stringify(item),
        }).then(
            response => {
                console.log(response);
                toastr.success(item.name + ' added to cart!', 'Success');
            }).catch(error => {
                console.log(error);
                toastr.error('Something went wrong!', 'Error');
            });
},
Regarding the CSRF part, the `bootstrap.js` file that is imported in the first line of the main `app.js` file, loads the axios HTTP library, which automatically handles sending the CSRF token as a header based on the value of the "XSRF" token cookie. Moreover, the `window.axios.defaults.headers.common['X-Requested-With']` is set to "XMLHttpRequest." Based on the default comment, the application should be using csrf token automatically. I have also included the `csrf-token` in my header, which retrieves the csrf token. Despite all these settings, when I hit "addToCart," it returns a `419` axios error. Furthermore, I attempted to access `$request->session()->getId()` in the controller, to store the session data of the request since `session()->getId()` returns a new session ID for every request, but it throws an error that the session store is not set. If I add `middleware(['web'])` to the route, it still returns the axios `419` error, although I have included the csrf in meta. I cannot believe I am missing something so crucial.
Answers(1)
avatar
Tolerim
21 hours ago
Verified Answer
It seems like the issue here is with the session handling in Laravel. Laravel stores session data server-side and it generates a session ID to be used for that session. When you call session()->getId() in your controller, it should return the same session ID for the same client session. However, in your case, a new session is generated on every request, even though the session ID displayed in the blade template remains the same. This is likely because the session ID is being stored in a cookie, but the cookie is not being sent back to the server with subsequent requests. To fix this issue, you need to ensure that the session ID cookie is being sent back to the server with every request. You can do this by setting the withCredentials option to true in your axios.post() request, like so:
axios.post(
    'api/cart/add',
    {
        product_id: item.id,
        product_data: JSON.stringify(item),
    },
    {
        withCredentials: true, // This ensures that the session ID cookie is sent back to the server
    }
)
Additionally, it looks like you are already handling CSRF tokens correctly by loading the Axios HTTP library, which automatically sets the CSRF token as a header based on the value of the "XSRF" token cookie. So you don't need to manually include the CSRF token in your header. Regarding the 419 "unknown status" error, this is likely a CSRF token mismatch issue. When you include the csrf-token meta tag in your header, Laravel automatically adds a X-CSRF-TOKEN header to your Axios requests. However, you also need to include the _token field in your request payload, like so:
axios.post(
    'api/cart/add',
    {
        product_id: item.id,
        product_data: JSON.stringify(item),
        _token: '{{ csrf_token() }}', // Include the CSRF token in the request payload
    },
    {
        withCredentials: true, // This ensures that the session ID cookie is sent back to the server
    }
)
Finally, regarding the Session store not set on request error, this occurs because you are trying to access the session data before it has been initialized. Middleware that is responsible for initializing the session should be applied to the relevant routes. You can apply the web middleware to your routes in the routes/web.php file, like so:
Route::group(['middleware' => ['web']], function () {
    // Your routes here
});
This will ensure that the session is initialized before your routes are accessed.
;