如何创建Laravel Gate要求客户端调用API时在请求头携带CSRF _token
实现Laravel Gate验证CSRF Token
1. 在AuthServiceProvider中定义Gate规则
打开app/Providers/AuthServiceProvider.php,在boot方法中添加Gate定义,用于校验请求头中的CSRF Token有效性:
use Illuminate\Support\Facades\Gate; use Illuminate\Http\Request; public function boot() { $this->registerPolicies(); Gate::define('validate-csrf', function ($user, Request $request) { // 从请求头提取CSRF Token $requestToken = $request->header('X-CSRF-TOKEN'); // 安全对比请求Token与会话中存储的Token return hash_equals(session()->token(), $requestToken); }); }
2. 在路由中应用Gate验证
修改routes/api.php中的目标路由,添加web中间件(启用会话支持,API路由默认无会话)和can中间件绑定Gate规则:
Route::get('/third-party/unsplash', [UnsplashController::class, 'show']) ->middleware(['web', 'can:validate-csrf']);
3. 前端请求携带CSRF Token
更新Vue组件的请求代码,在请求头中加入X-CSRF-TOKEN。Laravel会自动在页面meta标签中注入该Token,直接提取使用即可:
const myAsync = async function fetchUnsplash() { // 从页面meta标签获取CSRF Token const csrfToken = document.querySelector('meta[name="csrf-token"]').content; const myAPIKey = await fetch( 'http://127.0.0.1:50004/api/third-party/unsplash', { headers: { 'X-CSRF-TOKEN': csrfToken } } ); const dataMyAPIKey = await myAPIKey.json(); const response = await fetch('https://api.unsplash.com', { headers: { Authorization: dataMyAPIKey.authorizationKey, // 修正原代码:需提取对象属性而非直接传入对象 }, }); console.log(response); };
关键说明
- API路由默认无会话支持,因此必须添加
web中间件才能访问会话中的CSRF Token进行校验。 - 使用
hash_equals函数对比Token可避免时序攻击,提升验证安全性。 - 前端必须通过Laravel注入的meta标签获取Token,确保每次请求携带的Token与服务器会话一致。
内容的提问来源于stack exchange,提问作者Qais Wardag
相关产品推荐
相关产品推荐

