7

I am using Laravel with default integration of Vue (Not separate project using Vue CLI). I'm trying to authenticate a user but it always shows 419 error. I have included the csrf token to the Axios's header but it still provides mismatch error.

bootstrap.js

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.withCredentials = true;
window.axios.defaults.baseURL = "http://localhost:8000/";
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = $('meta[name="csrf-token"]').attr('content');

Kernel.php

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

cors.php

'paths' => [
    'api/*',
    '/login',
    '/logout',
    '/sanctum/csrf-cookie'
],
.
.
.
'supports_credentials' => true,

web.php

Route::get('/{any?}', function() {
    return view('welcome');
});

Route::post('/login', 'AuthController@login');
Route::post('/logout', 'AuthController@logout');

LoginModal.vue

<template>
    <form @submit.prevent="submit" method="POST">
        <input type="text" class="form-control" placeholder="Email" v-model="email" />
        <input
            type="password"
            class="form-control"
            placeholder="Password"
            v-model="password"
        />

        <button>SIGN IN</button>
    </form>
</template>

<script>
import { mapActions } from 'vuex'

export default {
    data() {
        return {
            email: '',
            password: '',
        }
    },
    methods: {
        ...mapActions('user', ['login']),
        async submit() {
            await this.login({
                email: this.email,
                password: this.password,
            })

            this.$router.replace({ name: 'Topic' })
        },
    },
}
</script>

user.js | Vuex modules

async login({ dispatch }, credentials) {
    await axios.get('/sanctum/csrf-cookie')
    await axios.post('/login', credentials)

    return dispatch('me')
},

I am configuring my project similar to this article. His is a separate project while mine within the Laravel project. I've also refer to Laravel's sanctum documentation on configuring authentication and it still didn't work. Review a lot of StackOverflow Q&A and no luck thus far. Most are talking about adding CSRF headers to Axios which I've done already within bootstrap.js. I did try including a hidden input to hold the CSRf and still no luck.

Afiq Rosli
  • 357
  • 1
  • 7
  • 22

4 Answers4

8

Did you remember to check your config/session.php domain?.

    /*
    |--------------------------------------------------------------------------
    | Session Cookie Domain
    |--------------------------------------------------------------------------
    |
    | Here you may change the domain of the cookie used to identify a session
    | in your application. This will determine which domains the cookie is
    | available to in your application. A sensible default has been set.
    |
    */
    'domain' => env('SESSION_DOMAIN', null),

And then SESSION_DOMAIN in .env should be .localhost

Also, did you remember to check config/sanctum.php stateful?

    /*
    |--------------------------------------------------------------------------
    | Stateful Domains
    |--------------------------------------------------------------------------
    |
    | Requests from the following domains / hosts will receive stateful API
    | authentication cookies. Typically, these should include your local
    | and production domains which access your API via a frontend SPA.
    |
    */
    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1')),

With SANCTUM_STATEFUL_DOMAINS in .env being localhost,127.0.0.1?

gofish
  • 347
  • 3
  • 10
2

SESSION_DOMAIN=localhost SANCTUM_STATEFUL_DOMAINS=localhost

this two lines worked for me.

Mir Tanvir Ahmed
  • 109
  • 1
  • 1
  • 7
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 26 '22 at 11:46
  • That did trick for me. Thanks! – henrbu Apr 28 '23 at 09:16
1

Enable cookie encryption

In my case it was the encrypt session / cookies functionality that wasn't activated everywhere (it was inconsistent). In my case, I had to activate it. If you disable it, make sure it is disabled everywhere. Otherwise Laravel will compare encrypted with unencrypted values and claim they are not the same.

Check all places where this could possibly be set:

  • config/session.php:

'encrypt' => false,

  • Kernel.php middleware
protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
  • Laravel Sanctum config/sanctum.php:

'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,

URL decode encrypted tokens

Additionally, my client sent the encrypted data URL encoded, which led the = at the end to become %3D. More details about that particular issue can be found in this answer.

askuri
  • 345
  • 3
  • 10
0

Instead of trying to add the cookie into your headers make the following get request at the top of your VUEX method.

await axios.get('http://localhost:8000/sanctum/csrf-cookie');

This will append the csrf cookie. Also set your session driver and domain accordingly within your env file.

SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost