我的应用在前端使用React,在后端使用Laravel 5.4。我使用fetch()
从后端请求数据。问题是页面加载时会创建两个会话。当发出TokenMismatchException
请求时,CSRF中间件会抛出POST
,因为发送的令牌与创建的第一个会话匹配,但它会检查第二个会话。
我在app.blade.php
<meta name="_token" content="{{ csrf_token() }}">
抓取fetch配置中的令牌
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
请求时阻止创建新会话?
答案 0 :(得分:8)
Laravel会自动为应用程序管理的每个活动用户会话生成CSRF“令牌”。此令牌用于验证经过身份验证的用户是否是实际向应用程序发出请求的用户。 :https://laravel.com/docs/5.4/csrf
API是无状态的。 API中没有类似session
的内容。所以你不应该在API中使用CSRF令牌。如果你检查laravel的Kernel.php
。您将看到Tylor未在API组中添加VerifyCsrf
中间件。这表明CSRF
仅用于具有会话的请求,即有状态请求。我建议你使用基于JWT的API身份验证系统。有关JWT的更多信息check here。
您可以将此laravel包用于JWT:https://github.com/tymondesigns/jwt-auth
答案 1 :(得分:5)
我不确定您的请求网址是什么以及您的目标API网址是什么。确保两者都在同一个域(包括子域)。
我认为仅对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