5

I have a Nuxt-Laravel-Sanctum CSRF token mismatch 419 error while Laravel is hosted on a server and Nuxt is on localhost on a PC. I have uploaded my Laravel project for getting API on api.repairtofix.com.

And I am trying to log in from localhost in my pc from Nuxt. While clicking on the login button I get the following error.

{message: "CSRF token mismatch.", exception: "Symfony\Component\HttpKernel\Exception\HttpException",…}

Login method

login() {
    this.$auth.loginWith('laravelSanctum', { 
        data: this.form 
    })
    .then(response => console.log(response))
    .catch(error => console.log(response))
}

.env

APP_URL=http://api.repairtofix.com
SESSION_DOMAIN=api.repairtofix.com
SANCTUM_STATEFUL_DOMAINS=.repairtofix.com,localhost:3000

Kernel.php

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

sanctum.php

'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 
    'api.repairtofix.com,localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1'
)),

cors.php

'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'signup', 'getUser'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,

api.php

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

// register
Route::get('register', function(Request $request){
    $user = User::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => bcrypt($request->password)
    ]);

    return $user;
});

// login
Route::post('login', function(Request $request){
    $credentials = $request->only('email', 'password');
    if(!auth()->attempt($credentials)){
        throw ValidationException::withMessages([
            'email' => 'Invalid credentials'
        ]);
    }

    $request->session()->regenerate();
    return response()->json(null, 201);
});

// logout
Route::post('logout', function(Request $request){
    auth()->guard('web')->logout();
    $request->session()->invalidate();
    $request->session()->regenerateToken();
    return response()->json(null, 201);
});

nuxt.config.js

modules: [
    '@nuxtjs/axios',
    '@nuxtjs/pwa',
    '@nuxtjs/auth-next',
    '@nuxtjs/toast',
],

auth:{
    strategies: {
        'laravelSanctum': {
            provider: 'laravel/sanctum',
            url: 'http://api.repairtofix.com',
            endpoints: {
                login: {
                    url: '/api/login'
                },
                logout: {
                    url: '/api/logout'
                },
                user: {
                    url: '/api/user'
                },
            },
            user: {
                property: false
            }
        },
    },
    redirect: {
        login: "/login",
        logout: "/",
        home: "/"
    }
},
1
  • You need to use token-based authentication in this case. Stateful domains and "EnsureFrontendRequestsAreStateful" are using Laravel's session cookie-based authentication, which is only working when both application share the same top-level domain. Commented Jun 1, 2021 at 20:11

5 Answers 5

2

I guess you are using SPA authentication with sanctum, both your server and client has to be on the same domain. The client(localhost) and your api is on different domain.

docs

In order to authenticate, your SPA and API must share the same top-level domain. However, they may be placed on different subdomains.

Sign up to request clarification or add additional context in comments.

3 Comments

This enlightened me, thanks. I have my backend and frontend on different domains and nothins was working. I didn't notice that they can be on different subdomains but under the same top-level domain. I guess I will have to use token-based authentication now (JWT).
UPDATE: I completely forgot that I don't even need to implement JWT because that would be much complicated unnecessary. Instead I added a CNAME to my domain DNS settings so now both of them live under the same domain like this: laravel backend -> api.mydomain.com nextjs frontend -> mydomain.com and it works!
Yeah, that is a common approach.
0

In my case, Axios credentials were not set to true in nuxt.config file, also the text is case sensitive


  axios: {
    baseUrl: 'http://localhost:8000',
    credentials: true,
  },

Comments

0

It is maybe a little bit late but others in future. 1-check the api/config/sanctum in laravel and make the ports correct on localhost:xxxx and 127.0.0.1:xxxx 2-on .env file make coorection for SANCTUM_STATEFUL_DOMAINS=localhost:xxxx

Comments

0

Add the below statement to your .env file and clear the cache.

AIRLOCK_STATEFUL_DOMAINS=127.0.0.1

Comments

0

Experiencing a CSRF token mismatch error, particularly a 419 error, in a Nuxt-Laravel-Sanctum setup can be challenging but is a common issue related to web application security. This error occurs when the CSRF token used in a request does not match the one expected by the Laravel backend, often due to token expiration or misconfiguration.

Generally you have to first call.

await axios.get("http://127.0.0.1:8000/sanctum/csrf-cookie");

Before

await axios.get("http://127.0.0.1:8000/bah/bah/bal");

Note: the base urls must be consistent do not use "localhost" to get the csrf-cookie then "127.0.0.1" to call your api.

Stick with one. For me i prefer 127.0.0.1

For a thorough explanation and a solution to this issue, I recommend watching this detailed video. It provides an in-depth look into the matter, enhancing your understanding of the situation.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.