React Fetch 到 Laravel API 创建新会话

Posted

技术标签:

【中文标题】React Fetch 到 Laravel API 创建新会话【英文标题】:React Fetch to Laravel API Creates New Session 【发布时间】:2017-09-09 22:58:25 【问题描述】:

我的应用在前端使用 React,在后端使用 Laravel 5.4。我正在使用fetch() 从后端请求数据。问题是页面加载时会创建两个会话。当发出 POST 请求时,CSRF 中间件会抛出 TokenMismatchException,因为发送的令牌与创建的第一个会话匹配,但它会检查第二个会话。

我在app.blade.php中设置令牌

<meta name="_token" content=" csrf_token() ">

并在获取配置中获取令牌

fetchConfig = 
    headers:  
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
    ,
    credentials: 'same-origin'

以下是解密的会话:

a:3:s:6:"_token";s:40:"7obvOzPaqqJDtVdij8RaqrvmTFLjKA2qnvYMxry6";s:9:"_previous";a:1:s:3:"url";s:24:"http://localhost/page";s:6:"_flash";a:2:s:3:"old";a:0:s:3:"new";a:0:

a:3:s:6:"_token";s:40:"5Aiws9Qy72YzlkfWX81zkhzrSeiMDYjFWiLeDAwN";s:9:"_previous";a:1:s:3:"url";s:41:"http://localhost/api/page";s:6:"_flash";a:2:s:3:"old";a:0:s:3:"new";a:0:

请求网址:http://localhost/page

API 网址:http://localhost/api/page

当 React 应用发出初始 GET 请求时,如何防止创建新会话?

【问题讨论】:

您使用的是哪个会话驱动程序? 我正在使用file 会话驱动程序。 如果你对 Laravel API 使用了 JWT Auth(JSON Web Token Authentication) 令牌。因为 API 无法维护状态。因此,如果您需要 Csrf Token 验证,则必须将其作为私有声明存储在元标记或 JWT 有效负载中。 @bill 你有没有想过如何防止创建多个会话? 【参考方案1】:

Laravel 会为应用程序管理的每个活动的用户会话自动生成一个 CSRF“令牌”。此令牌用于验证经过身份验证的用户是实际向应用程序发出请求的用户。 :https://laravel.com/docs/5.4/csrf

API 是无状态的。 API 中没有像 session 这样的东西。所以你不应该在 API 中使用 CSRF 令牌。如果你检查 laravel 的Kernel.php。你会看到 Tylor 没有在 API 组中添加 VerifyCsrf 中间件。这表明CSRF 仅用于具有会话的请求,即有状态的请求。我建议您使用基于 JWT 的 API 身份验证系统。更多关于智威汤逊check here。

您可以将此 laravel 包用于 JWT:https://github.com/tymondesigns/jwt-auth

【讨论】:

【参考方案2】:

我不确定您的请求 URL 是什么以及您的目标 API url 是什么。确保两者都在同一个域(包括子域)上。

我认为仅对 API 路由禁用 CSRF 验证是个好主意,因为这些路由可能会被其他域、本机应用程序等使用

您可以通过添加以下类文件来做到这一点:app/Http/Middleware/VerifyCsrfToken.php

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier

    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'api/*',
    ];

确保编辑 Kernal.php 以指向新类:

protected $middleware = [
    'csrf' => 'App\Http\Middleware\VerifyCsrfToken'
];

要了解更多 Laravel 如何使用 CSRF,请查看this laracast video

【讨论】:

感谢您的回答!我将请求和 api url 添加到问题中,因为它们隐藏在会话数据中。您的解决方案可以绕过 csrf 中间件,但仍在创建多个会话。如果可能的话,我希望能解决这个问题。

以上是关于React Fetch 到 Laravel API 创建新会话的主要内容,如果未能解决你的问题,请参考以下文章

React JS Fetch 返回空响应,但 Postman 没有

Android上的React Native Fetch返回网络请求失败

如何在变量Fetch API中存储异步数据

如何通过ajax fetch api响应将从laravel控制器接收到的数据发送到另一个页面

如何使用 React.js 中的 Fetch API 将数据发布到数据库

调用 Fetch API 后没有得到任何东西 - React Native