反应前端中的 CSRF 令牌不匹配
Posted
技术标签:
【中文标题】反应前端中的 CSRF 令牌不匹配【英文标题】:CSRF token mismatch in react front end 【发布时间】:2021-10-04 03:02:58 【问题描述】:我是 laravel 的新手。我正在为基于 API 的电子商务开发一个注册模块,使用 Laravel 作为 API 后端,react.js 作为前端。 该 api 使用 laravel/sanctum 认证包。完成所有必要的配置后,注册返回 419 错误状态并显示以下消息:
"message": "CSRF token mismatch.",
"exception": "Symfony\\Component\\HttpKernel\\Exception\\HttpException",
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Exceptions\\Handler.php",
"line": 387,
"trace": [
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Exceptions\\Handler.php",
"line": 332,
"function": "prepareException",
"class": "Illuminate\\Foundation\\Exceptions\\Handler",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php",
"line": 51,
"function": "render",
"class": "Illuminate\\Foundation\\Exceptions\\Handler",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 172,
"function": "handleException",
"class": "Illuminate\\Routing\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Session\\Middleware\\StartSession.php",
"line": 121,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Session\\Middleware\\StartSession.php",
"line": 64,
"function": "handleStatefulRequest",
"class": "Illuminate\\Session\\Middleware\\StartSession",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Illuminate\\Session\\Middleware\\StartSession",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse.php",
"line": 37,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Cookie\\Middleware\\EncryptCookies.php",
"line": 67,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Illuminate\\Cookie\\Middleware\\EncryptCookies",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\sanctum\\src\\Http\\Middleware\\EnsureFrontendRequestsAreStateful.php",
"line": 26,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 149,
"function": "Laravel\\Sanctum\\Http\\Middleware\\closure",
"class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 103,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\sanctum\\src\\Http\\Middleware\\EnsureFrontendRequestsAreStateful.php",
"line": 34,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 103,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
"line": 697,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
"line": 672,
"function": "runRouteWithinStack",
"class": "Illuminate\\Routing\\Router",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
"line": 636,
"function": "runRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
"line": 625,
"function": "dispatchToRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
"line": 166,
"function": "dispatch",
"class": "Illuminate\\Routing\\Router",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 128,
"function": "Illuminate\\Foundation\\Http\\closure",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
"line": 21,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull.php",
"line": 31,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
"line": 21,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TrimStrings.php",
"line": 40,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php",
"line": 27,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance.php",
"line": 86,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\fruitcake\\laravel-cors\\src\\HandleCors.php",
"line": 52,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Fruitcake\\Cors\\HandleCors",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\fideloper\\proxy\\src\\TrustProxies.php",
"line": 57,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 167,
"function": "handle",
"class": "Fideloper\\Proxy\\TrustProxies",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 103,
"function": "Illuminate\\Pipeline\\closure",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
"line": 141,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
"line": 110,
"function": "sendRequestThroughRouter",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\public\\index.php",
"line": 52,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
,
"file": "C:\\Users\\DELL\\web projects\\development\\api_arms\\server.php",
"line": 21,
"function": "require_once"
]
我需要帮助来解决这个问题。
这是我的源文件:
AuthController.php
:
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\User;
use http\Env\Response;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class AuthController extends Controller
public function register(Request $request)
$validator = Validator::make($request->all(),[
'name'=>'required',
'email'=>'required|email|max:191|unique:users,email',
'password'=>'required|min:6'
]);
if ($validator->fails())
return response()->json([
'error'=>$validator->messages()
]);
else
$user = User::create([
'name'=>$request->name,
'email'=>$request->email,
'password'=>Hash::make($request->password)
]);
$token = $user->createToken($user->email.'_Token')->plainTextToken;
return response()->json([
'status'=>200,
'usename'=>$user->name,
'token'=>$token,
'message'=>'Registered successfully'
]);
User.php
:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
cors.php
:
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
];
api.php
:
<?php
use App\Http\Controllers\API\AuthController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::post('register',[AuthController::class,'register']);
frontends configurations.
App.js.
axios.defaults.baseURL="http://127.0.0.1:8000";
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.headers.post['Accept'] = 'application/json';
axios.defaults.withCredentials = true;```
eRegister.js.
import React, useState from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import axios from "axios";
class eRegister extends React.Component
constructor(props)
super(props);
this.state=
name:"",
email:"",
password:""
registerData=(event)=>
const value = event.target.value;
const name = event.target.name;
this.setState(
[name]:value
)
register=()=>
console.log(this.state);
axios.get('/sanctum/csrf-cookie').then(response =>
axios.post('api/register').then(response=>
)
);
render()
return(
<div>
<form>
<label>Name:</label><input type="text" name="name" onChange=this.registerData/>
<label>Email:</label><input type="text" name="email" onChange=this.registerData/>
<label>Password</label><input type="password" name="password" onChange=this.registerData/>
<button type="button" onClick=()=>this.register()>Register</button>
</form>
</div>
)
export default eRegister;
【问题讨论】:
您是否将EnsureFrontendRequestsAreStateful
类添加到您的api
中间件组?
是的,我做到了,'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ],
【参考方案1】:
如果你使用 Laravel 作为 API。那么你不应该使用 CSRF 令牌。
CSRF 验证中间件是为 Web 路由设置的,而不是为 API 设置的。
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,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
【讨论】:
laravel.com/docs/8.x/sanctum#spa-authentication以上是关于反应前端中的 CSRF 令牌不匹配的主要内容,如果未能解决你的问题,请参考以下文章