Laravel 7 Vue 2 Sanctum Ошибка входа в систему 419; Несоответствие токенов CSRF

Я использую Laravel со стандартной интеграцией Vue (не отдельный проект, использующий Vue CLI). Я пытаюсь аутентифицировать пользователя, но всегда показывает ошибку 419. Я включил токен csrf в заголовок Axios, но он по-прежнему выдает ошибку несоответствия.

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

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

    return dispatch('me')
},

Я настраиваю свой проект аналогично этому статья. Это отдельный проект, а мой - в рамках проекта Laravel. Я также обращался к документации Laravel sanctum по настройке аутентификации, но она по-прежнему не работала. Просмотрите множество вопросов и ответов о StackOverflow, и пока все безуспешно. Большинство из них говорят о добавлении заголовков CSRF в Axios, что я уже сделал в bootstrap.js. Я попытался включить скрытый ввод для хранения CSRf, но все равно не повезло.


person Afiq Rosli    schedule 21.08.2020    source источник


Ответы (3)


Вы не забыли проверить свой config/session.php домен ?.

    /*
    |--------------------------------------------------------------------------
    | 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),

И тогда SESSION_DOMAIN в .env должен быть .localhost

Кроме того, вы не забыли проверить config/sanctum.php отслеживание состояния?

    /*
    |--------------------------------------------------------------------------
    | 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')),

Если SANCTUM_STATEFUL_DOMAINS в .env составляет localhost,127.0.0.1?

person gofish    schedule 21.08.2020
comment
Я сделал то, что вы меня просили, но ошибка 419 все еще выдается даже после php artisan config:cache - person Afiq Rosli; 21.08.2020
comment
К какому URL вы получаете доступ в браузере? - person gofish; 21.08.2020
comment
У меня была проблема с 419, и я решил ее, только очистив параметр состояния в config/sanctum.php - person Serhii Topolnytskyi; 30.12.2020
comment
Установка session_domain в .localhost сделала для меня волшебство. Большое спасибо! - person Svetoslav Stefanov; 16.04.2021

Включить шифрование файлов cookie

В моем случае это была функция шифрования сеанса / файлов cookie, которая не была активирована везде (она была несовместимой). В моем случае мне пришлось активировать его. Если вы отключите его, убедитесь, что он отключен везде. В противном случае Laravel будет сравнивать зашифрованные и незашифрованные значения и утверждать, что они не совпадают.

Отметьте все места, где это возможно установить:

  • config / session.php:

'encrypt' => false,

  • Промежуточное ПО Kernel.php
protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
  • Конфигурация Laravel Sanctum / sanctum.php:

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

URL-декодирование зашифрованных токенов

Кроме того, мой клиент отправил зашифрованный URL-адрес с закодированными данными, в результате чего знак = в конце стал% 3D. Более подробную информацию об этой конкретной проблеме можно найти в этом ответе.

person askuri    schedule 25.03.2021

Вместо того, чтобы пытаться добавить файл cookie в заголовки, сделайте следующий запрос на получение в верхней части вашего метода VUEX.

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

Это добавит файл cookie csrf. Также установите драйвер сеанса и домен соответственно в файле env.

SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
person Edward William Sams    schedule 13.07.2021