You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Laravel中的一组GET路由开启CSRF保护?

解决方案

推荐方案:将GET路由改为POST请求

Laravel的CSRF保护默认针对非幂等请求(如POST/PUT/DELETE等),因为GET请求语义上是用于获取数据、不修改服务器状态的操作,通常无需CSRF保护。如果你的这些接口实际会修改数据(或需要严格验证请求来源),最优雅的方式是遵循HTTP语义,将路由改为POST:

  1. 修改路由定义:
Route::post('/location/get', 'Ajax@getProducts');
Route::post('/products/get', 'Ajax@getProducts');
Route::post('/schedule/get', 'Ajax@getProducts');
  1. 前端请求时携带CSRF令牌:
    • 表单提交时添加隐藏字段:
      <input type="hidden" name="_token" value="{{ csrf_token() }}">
      
    • AJAX请求(如Axios)时,确保页面头部有meta标签,Axios会自动读取并加入请求头:
      <meta name="csrf-token" content="{{ csrf_token() }}">
      

备选方案:为GET路由手动添加CSRF验证(仅用于无法改POST的场景)

如果因业务限制必须保留GET请求,可通过自定义中间件或控制器内验证的方式实现,避免修改框架核心逻辑:

方式1:自定义中间件验证CSRF

  1. 创建中间件:
php artisan make:middleware VerifyCsrfForGet
  1. 编写中间件验证逻辑:
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;

class VerifyCsrfForGet
{
    public function handle($request, Closure $next)
    {
        $token = $request->query('_token');
        
        try {
            // 验证令牌有效性与过期时间
            Crypt::decrypt($token, true);
        } catch (DecryptException $e) {
            abort(419, 'CSRF令牌无效或已过期');
        }

        return $next($request);
    }
}
  1. 在app/Http/Kernel.php注册中间件:
protected $routeMiddleware = [
    // ...其他中间件
    'csrf.get' => \App\Http\Middleware\VerifyCsrfForGet::class,
];
  1. 为目标路由绑定该中间件:
Route::get('/location/get', 'Ajax@getProducts')->middleware('csrf.get');
Route::get('/products/get', 'Ajax@getProducts')->middleware('csrf.get');
Route::get('/schedule/get', 'Ajax@getProducts')->middleware('csrf.get');
  1. 前端请求时在URL参数中携带令牌:
// Axios示例
axios.get('/location/get', {
    params: {
        _token: document.querySelector('meta[name="csrf-token"]').content
    }
});

方式2:直接在控制器方法中验证

若不想创建中间件,可在Ajax@getProducts方法开头添加验证逻辑:

public function getProducts(Request $request)
{
    try {
        Crypt::decrypt($request->query('_token'), true);
    } catch (DecryptException $e) {
        abort(419, 'CSRF令牌无效');
    }

    // 原有业务逻辑代码
}

注意:强制为GET请求添加CSRF保护不符合HTTP语义规范,仅建议在特殊场景下使用,优先推荐改为POST请求。

内容的提问来源于stack exchange,提问作者Viewsonic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:30:44