1

I am working on an application that uses Laravel 8 in the backend and Nuxtjs in the frontend. My problem is that every time I make a request with Axios regardless of the method, Laravel creates a new session. This prevents me for example from checking the csrf cookie because each time a new session is generated. I don't really know what to do and I would like to get your help please...

sample code to get the session token :

Route::get('/test', function() {
    return request()->session()->token();
});

First attempt : IM23wUv9NTY2IUu9gAJix6TTg3IFjjgOkasOkRhn

Second attempt : bMpuaa9Ink4dOUUJNEyJnbYYKSqSACP216Xq08Uh

Therefore, I always get a 419 for each of my requests.

Code:

const self = this
const rootURL = self.$axios.defaults.baseURL.replace('/api', '')
self.$axios.get('/sanctum/csrf-cookie', {
  baseURL: rootURL
}).then(() => {
  self.$axios.post('/auth/login', {
    email: self.email,
    password: self.password,
  }, {withCredentials: true}).then(({data: response}) => {
    console.log(response)
  })
})

Response:

{
    "message": "CSRF token mismatch.",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\HttpException",
    "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
    "line": 387,
    "trace": [
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
            "line": 332,
            "function": "prepareException",
            "class": "Illuminate\\Foundation\\Exceptions\\Handler",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 51,
            "function": "render",
            "class": "Illuminate\\Foundation\\Exceptions\\Handler",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 172,
            "function": "handleException",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php",
            "line": 121,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php",
            "line": 64,
            "function": "handleStatefulRequest",
            "class": "Illuminate\\Session\\Middleware\\StartSession",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Session\\Middleware\\StartSession",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php",
            "line": 37,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php",
            "line": 67,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Cookie\\Middleware\\EncryptCookies",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
            "line": 26,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "Laravel\\Sanctum\\Http\\Middleware\\{closure}",
            "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 103,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
            "line": 34,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 103,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 697,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 672,
            "function": "runRouteWithinStack",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 636,
            "function": "runRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 625,
            "function": "dispatchToRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 166,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 128,
            "function": "Illuminate\\Foundation\\Http\\{closure}",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
            "line": 31,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
            "line": 40,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
            "line": 27,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
            "line": 86,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/fruitcake/laravel-cors/src/HandleCors.php",
            "line": 52,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Fruitcake\\Cors\\HandleCors",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/fideloper/proxy/src/TrustProxies.php",
            "line": 57,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Fideloper\\Proxy\\TrustProxies",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 103,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 141,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 110,
            "function": "sendRequestThroughRouter",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/public/index.php",
            "line": 52,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/sidik/Projets/Colisone/web/laravel-backend/server.php",
            "line": 21,
            "function": "require_once"
        }
    ]
}
sidikfaha
  • 139
  • 3
  • 12

3 Answers3

5

Sessions on servers are used to store some user data (IP, authentication, etc). So because API's are stateless (server doesn't need to know about user) it seems like server generates a new session for every request and it's logical.

What you should do is make your app in a way that it does not need session data (stateless).

I do not recommend that you do otherwise and have never done it before so I don't know if it works but if you absolutely need the sessions then you must look at kernel.php file.

In $middlewareGroups array's api you can add

\Illuminate\Session\Middleware\StartSession::class, to beginning of the array like this :

    'api' => [
        \Illuminate\Session\Middleware\StartSession::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

OR

Generate a session for user in login (where you assign them a token), store that session to database (create a sessions table). Then create a middleware that checks if the the user that is making a request has any session in database. if yes assign that session to current user. and add it in to the routes that you need.

If in a situation I need to do something like this I would choose option 2 because first I don't think the first one solves your problem, second the later way still enables me to scale my app without worry (I would need to separate my db server anyway) .

you can search about ways to have session on API's on google. you may find something that may suit you more.

Amir Daneshkar
  • 771
  • 3
  • 9
4

Is this or this answer your question?

Like:

Inside your config/session.php

  • Make sure the domain is set to the correct path or null
  • Change the secure to true 'secure' => env('SESSION_SECURE_COOKIE', true) (or if not using SSL, try with false)
  • Try without https
  • Make sure the cookie does not contain . (dot) or try without _ underscore in it

Or another approach:

Like this answer tells you, try to append a new middleware if you are appending the header via JS

Another solution if there is a blade view, try put this in it:

<script>window.Laravel = {csrfToken: '{{ csrf_token() }}'}</script>

and in the bootstrap.js file:

window.axios  = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = window.Laravel.csrfToken;
treb
  • 173
  • 2
  • 10
1

A guiding answer:

PHP stores sessions and checks requests by looking cookies for a session id in order to find whether there is a session with that id in its session storage(files on each server if you do not configure it to use a database or redis) or not.

In a request,

  • if there is no cookie, a new session is created.
  • If there is a cookie containing session id and it is found in the session storage, that session is used.
  • If there is a cookie containing session id and it is not found in the session storage, again a new session is created.

1.If you use an API server and do not use cookies and do not send any session ids around, you have to use a method to authenticate your requests. (For example, an authentication token. You can also check laravel passport). Your way to the solution should be to investigate the API authentication methods.

2.If you do use sessions,

  • You have to check your requests whether they are containing cookies carrying session ids. If not, you should find a fix for that
  • If there is cookies, you should check session ids sent in each request. Are they changing in every request? Or are they same? You have to figure out two things here:
    • If session ids are same in each request, you should debug your server side to find why php cannot find your session although there is a session id in the request and creates a new one (do not forget to check if the session id is stored in the session storage). Paradoxically, if you find that php creates a new session although there is a session id in the request, the session ids in requests should not be the same since php tells your client to store the new session id by sending a cookie in response.
    • If session ids are different in each request, probably, your server does not handle sessions properly as mentioned in upper bullet or it is totally configured not to use sessions. It may be configured to run stateless and you should focus the things I talked about in 1. Also, you can pay attention what Amir Daneshkar said in his response.

I hope this helps you and the many who do not have sufficient information about cookies.

Onur Demir
  • 708
  • 2
  • 13
  • 35