Laravel 7 Vue 2 Sanctum登录错误419; CSRF令牌不匹配

时间:2020-08-21 17:18:04

标签: laravel vue.js single-page-application csrf laravel-sanctum

我正在使用Laravel与Vue的默认集成(不是使用Vue CLI的单独项目)。我正在尝试验证用户,但始终显示419错误。我在Axios的标头中包含了csrf令牌,但它仍然提供不匹配错误。

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')
},

我正在配置与此article类似的项目。他是Laravel项目中的一个独立项目。我还参考了Laravel有关配置身份验证的圣所文档,但该文档仍然无法正常工作。复习大量StackOverflow问答,到目前为止,还没有运气。大多数人都在谈论将CSRF标头添加到Axios,我已经在bootstrap.js中完成过。我确实尝试过包含一个隐藏的输入来保存CSRf,但仍然没有运气。

3 个答案:

答案 0 :(得分:0)

您还记得检查过您的set PATH=%PATH%;C:\Users\name\AppData\Local\Programs\Python\Python38-32 域吗?

config/session.php

然后,.env中的SESSION_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),

还,您还记得检查.localhost是否有状态吗?

config/sanctum.php

.env中的SANCTUM_STATEFUL_DOMAINS是 /* |-------------------------------------------------------------------------- | 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')), 吗?

答案 1 :(得分:0)

启用 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。有关该特定问题的更多详细信息,请参见 this 答案。

答案 2 :(得分:0)

不要尝试将 cookie 添加到标头中,而是在 VUEX 方法的顶部发出以下 get 请求。

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

这将附加 csrf cookie。还要在您的 env 文件中相应地设置您的会话驱动程序和域。

SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost