首页 > 解决方案 > Laravel Sanctum & React 与 Axios,POST 返回 419

问题描述

这几天我一直很绝望,因为我似乎无法克服这个简单的问题。

我无法验证由 Sanctum Laravel 提供支持的 SPA(通过 Axios 做出反应)

我已阅读文档并阅读 man 教程和问题。我已经克服了一些问题。

最终,我坚持了这一点:

我的请求包含 X-CSRF-TOKEN,但它总是返回 419“消息:CSRF 令牌不匹配”。

这是我的网络页面的屏幕截图:

在此处输入图像描述 在此处输入图像描述

可以看出,“登录”发布请求已经发送了 CSRF 令牌。第二张图片是同一请求的 cookie 选项卡。

但最后还是返回了 419

我目前不知道该怎么做

请帮忙

非常感谢你

PS由于我目前迷路了,我不知道应该附上我的代码的哪一部分,所以为了让大家免于阅读大量无用的代码部分,我没有将它们全部发布在我最初的问题上,但是无论如何,请要求我应该附加哪部分代码以进一步澄清我的问题

附件:

Laravel 的 .env

SESSION_DRIVER=cookie
SESSION_LIFETIME=120
SESSION_SECURE_COOKIE=false
SESSION_DOMAIN=.localhost
SANCTUM_STATEFUL_DOMAINS=localhost:3000,localhost:8000,127.0.0.1:3000,127.0.0.1:8000

我的反应 axios 功能

export const sendLogin = (data) => {
    axios.defaults.withCredentials = true;
    const response = axios.get(apiUrl('sanctum/csrf-cookie','backend-non-api-route')).then(response => {
        return axios.post(apiUrl('user/login','backend-non-api-route'),data,{ 
            xsrfHeaderName: 'X-CSRF-Token',
            withCredentials: true
          });
    })
    return response;
}

注意:apiUrl() 函数只是附加 Laravel 的 URL

应用程序/http/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\HandleInertiaRequests::class,
        ],

        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            //\Illuminate\Session\Middleware\StartSession::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];
}

标签: phpreactjslaravelaxioslaravel-sanctum

解决方案


试试这个:

export const sendLogin = (data) => {
    axios.defaults.withCredentials = true;
    const response = axios.get(apiUrl('sanctum/csrf-cookie','backend-non-api-route')).then(response => {
        return axios.post(apiUrl('user/login','backend-non-api-route'),data,{ 
            xsrfHeaderName: "X-XSRF-TOKEN", // change the name of the header to "X-XSRF-TOKEN" and it should works
            withCredentials: true
          });
    })
    return response;
}

编辑:阅读 Sanctum 文档我得到了这个文档片段:

在这个请求期间,Laravel 将设置一个XSRF-TOKEN包含当前 CSRF 令牌的 cookie。然后,此令牌应X-XSRF-TOKEN在后续请求的标头中传递,某些 HTTP 客户端库(如 Axios 和 Angular HttpClient)会自动为您执行此操作。如果您的 JavaScript HTTP 库没有为您设置值,您将需要手动设置X-XSRF-TOKEN标头以匹配XSRF-TOKEN此路由设置的 cookie 的值。

这个另一个答案说你必须同时使用它们中的一个(X-CSRF-TOKENX-XSRF-TOKEN)。


推荐阅读