8

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

在此处输入图像描述

应用刀片:

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

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

4

4 回答 4

5

我遇到了这个问题。原因是未设置 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;
于 2020-12-09T14:28:03.440 回答
2

有时?!听起来像一个expired token.

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

location.reload()当你得到419 error code并且一切顺利时尝试。

于 2019-12-23T00:24:27.343 回答
0

我认为令牌在您的情况下已过期。您可以拦截 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)
    }
)
于 2021-09-16T13:15:27.080 回答
0

我在另一个网站(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/*',
        ];
    }
于 2022-01-31T19:58:38.943 回答