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

gv8xihay  于 2023-01-26  发布在  Vue.js
关注(0)|答案(5)|浏览(184)

我在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');
}

Kernel.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,
        ],

我试着清除缓存和配置没有结果。有什么想法如何解决它?

50pmv0ei

50pmv0ei1#

我遇到了这个问题。原因是没有设置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;
vojdkbi0

vojdkbi02#

有时候?!听起来像是。
当您在incognito tabs中工作时,您有一个新的令牌。
当你得到419 error code时,尝试location.reload(),一切都很顺利。

3qpi33ja

3qpi33ja3#

我认为您的令牌过期了,您可以拦截http status 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)
    }
)
vxbzzdmp

vxbzzdmp4#

我在另一个网站(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/*',
        ];
    }
dy1byipe

dy1byipe5#

请注意,客户端到服务器的http和https之间的差异也会导致此错误;这意味着,即使您的所有配置都是正确的,如果https没有强制执行,客户端使用http,那么这个错误就会产生。

相关问题