Laravel + Vue.js (axios) - CSRF 令牌不匹配

Posted

技术标签:

【中文标题】Laravel + Vue.js (axios) - CSRF 令牌不匹配【英文标题】:Laravel + Vue.js (axios) - CSRF token mismatch 【发布时间】:2020-04-14 08:19:35 【问题描述】:

我对 Laravel 中的 csrf 令牌有疑问。有时请求 POST(通过 axios)返回 419 代码“CSRF 令牌不匹配”,但请求标头包含 CSRF 和 XSRF 令牌。有趣的是,它不会在隐身模式下发生。

App.blade:

<meta name="csrf-token" content=" csrf_token() ">

bootstrap.js:

window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';


let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) 
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
 else 
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');

内核.php

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\Localization::class,
        ],

我试图清除缓存和配置,但没有结果。任何想法如何解决它?

【问题讨论】:

你说它有时有效有时无效?提交表单时会失败吗? 这是随机发生的(例如当用户尝试注销或通过表单发送消息时)。 我推荐this article。 【参考方案1】:

我在另一个网站 (webB) 中从 laravel 数据库 (webA) 中获取数据时遇到问题。 经过一番研究,我发现 Laravel 已经为这个场景提供了一个解决方案:https://laravel.com/docs/5.7/csrf 来排除你从另一个网站访问的路线。在VerifyCsrfToken.php中,排除路由或页面。

<?php
    
    namespace App\Http\Middleware;
    
    use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
    
    class VerifyCsrfToken extends Middleware
    
        /**
         * The URIs that should be excluded from CSRF verification.
         *
         * @var array
         */
        protected $except = [
            'stripe/*',
            'http://example.com/foo/bar',
            'http://example.com/foo/*',
        ];
    

【讨论】:

【参考方案2】:

我认为在您的情况下令牌已过期。你可以拦截 http 状态 419(Laravel 定义的非标准状态)并重新加载页面以生成新的 CSRF 令牌:

window.axios.interceptors.response.use(
    response => response.data,
    error => 
        if (error.response && 419 === error.response.status) 
            window.location.reload()
        

        return Promise.reject(error)
    
)

【讨论】:

【参考方案3】:

我遇到了这个问题。原因是未设置 axios 标头。将它们设置在组件内的轴对象上也不能解决问题。在定义对象后设置标题为我解决了这个问题。

在您的刀片视图中添加以下内容:

<script>window.Laravel = csrfToken: ' csrf_token() '</script>

在您的 bootstrap.js 文件中,在声明 window.axios = require('axios'); 之后添加以下内容:

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = window.Laravel.csrfToken;

【讨论】:

伙计,非常感谢你!我输了两天才找到你的答案!其作品!!!!是的! 给这个人一枚勋章!非常感谢你。 您好,我遇到了同样的问题,它非常零星,而且大多数时候设置了 XSRF 令牌。但是有时它不是,Kevin,你知道这种方法是否会与 axios 在 lararvel 中设置 XSRF 令牌的自动行为冲突吗?谢谢。【参考方案4】:

有时?!听起来像是expired token

当你在 incognito tabs 工作时,你有一个新的令牌。

当您收到419 error code 时尝试location.reload(),一切顺利。

【讨论】:

以上是关于Laravel + Vue.js (axios) - CSRF 令牌不匹配的主要内容,如果未能解决你的问题,请参考以下文章

从子组件更新数据 - Vue.js/Axios/Laravel

Laravel + Vue.js (axios) 使用网络路由 - 未经身份验证

在 Vue.js 中使用 axios 向 Laravel API 发送获取请求

在 axios 调用时,DOM 不显示 vue.js 和 laravel 中数组的更新数据

无法通过 Vue.js(Axios 帖子)从 Laravel 后端下载文件(pdf)

Vue Js - axios 的问题使用 laravel 执行多个并发请求