6

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

引导程序.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');

内核.php

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

cors.php

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

网页.php

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

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

登录模式.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>

用户.js | Vuex 模块

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

    return dispatch('me')
},

我正在配置与本文类似的项目。他是一个单独的项目,而我在 Laravel 项目中。我还参考了 Laravel 关于配置身份验证的 sanctum 文档,但它仍然不起作用。回顾了很多 StackOverflow 问答,到目前为止还没有运气。大多数人都在谈论向 Axios 添加 CSRF 标头,我已经在 bootstrap.js. 我确实尝试包括一个隐藏的输入来保存 CSRf,但仍然没有运气。

4

4 回答 4

9

你记得检查你的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),

然后 .env 中的 SESSION_DOMAIN 应该是.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')),

.env 中的 SANCTUM_STATEFUL_DOMAINS 是localhost,127.0.0.1

于 2020-08-21T17:46:28.897 回答
1

启用 cookie 加密

在我的例子中,加密会话/cookies 功能并没有在任何地方被激活(它是不一致的)。就我而言,我必须激活它。如果禁用它,请确保它在任何地方都被禁用。否则 Laravel 会将加密的值与未加密的值进行比较,并声称它们不一样。

检查所有可能设置的地方:

  • 配置/会话.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。可以在答案中找到有关该特定问题的更多详细信息。

于 2021-03-25T13:51:12.170 回答
0

SESSION_DOMAIN=localhost SANCTUM_STATEFUL_DOMAINS=localhost

这两行对我有用。

于 2022-01-25T20:01:35.577 回答
0

不要尝试将 cookie 添加到您的标头中,而是在您的 VUEX 方法的顶部执行以下获取请求。

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

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

SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
于 2021-07-13T02:41:05.393 回答