0
votes

I am have been very desperate for these few days because I seem can't overcome this one simple problem.

I can not authenticate my SPA (react via Axios) powered by Sanctum Laravel

I have read the documentation and read man tutorials and questions. Some problems have I overcome.

Eventually, I stuck in this one :

My request has contained the X-CSRF-TOKEN, but it always returns a 419 "message: CSRF token mismatch."

Here is the screenshot of my network page :

enter image description here enter image description here

As it can be seen, that the "login" post request has sent the CSRF token. On the second picture is the cookie tab of the same request.

But in the end, it returned 419

I'm currently at lost on what to do

Please help

Thank you very much

P.S. As I am currently lost, I don't know which part of my code should I attach, so from saving you all from reading an abundant amount of useless parts of the code, I did not post them all on my initial question, but by all mean, please request which part of code should I attach to further clarify my problem

Attachment:

Laravel's .env

SESSION_DRIVER=cookie
SESSION_LIFETIME=120
SESSION_SECURE_COOKIE=false
SESSION_DOMAIN=.localhost
SANCTUM_STATEFUL_DOMAINS=localhost:3000,localhost:8000,127.0.0.1:3000,127.0.0.1:8000

My react axios function

export const sendLogin = (data) => {
    axios.defaults.withCredentials = true;
    const response = axios.get(apiUrl('sanctum/csrf-cookie','backend-non-api-route')).then(response => {
        return axios.post(apiUrl('user/login','backend-non-api-route'),data,{ 
            xsrfHeaderName: 'X-CSRF-Token',
            withCredentials: true
          });
    })
    return response;
}

note : The apiUrl() function just appends the Laravel's URL

app/http/Kernel.php

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\HandleInertiaRequests::class,
        ],

        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            //\Illuminate\Session\Middleware\StartSession::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];
}
1
make sure that you add your laravel routes in the api file - Joseph
@Joseph yes, I have the 'user/login' route in my route/api.php as well as route/web.php. Though the react Axios post is sent to the [web] route - Gita Prasetya Adiguna
Can you share with us, your app/Http/Kernel.php file? - DaviMendesDev
@DaviMendesDev of course, i already updated my question to include the Kernel.php. Can you please kindly look? - Gita Prasetya Adiguna

1 Answers

0
votes

try this:

export const sendLogin = (data) => {
    axios.defaults.withCredentials = true;
    const response = axios.get(apiUrl('sanctum/csrf-cookie','backend-non-api-route')).then(response => {
        return axios.post(apiUrl('user/login','backend-non-api-route'),data,{ 
            xsrfHeaderName: "X-XSRF-TOKEN", // change the name of the header to "X-XSRF-TOKEN" and it should works
            withCredentials: true
          });
    })
    return response;
}

EDIT: Reading the Sanctum Documentation I get this snippet of doc:

During this request, Laravel will set an XSRF-TOKEN cookie containing the current CSRF token. This token should then be passed in an X-XSRF-TOKEN header on subsequent requests, which some HTTP client libraries like Axios and the Angular HttpClient will do automatically for you. If your JavaScript HTTP library does not set the value for you, you will need to manually set the X-XSRF-TOKEN header to match the value of the XSRF-TOKEN cookie that is set by this route.

and this another answer says that you have to use only one of them both (X-CSRF-TOKEN and X-XSRF-TOKEN), but actually, seems that axios set this automatically, so I think that when you set it again, you're actually dumping the csrf-token on request, so try to make the request without csrf-token setted because it's setted on cookie with axios