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

如何保护Laravel API的GET路由仅允许自身Vue前端访问不对外公开

Laravel无登录GET接口防第三方调用解决方案

以下是几种不同安全等级的实现方案,可根据你的需求选择:

方案1:同源校验(零前端改造成本)

适合要求较低的场景,通过校验请求来源是否为你的站点域名实现拦截:

  • 第一步:生成校验中间件
    执行命令:php artisan make:middleware CheckSameOrigin
  • 第二步:编写中间件校验逻辑
    打开app/Http/Middleware/CheckSameOrigin.php,写入代码:
    public function handle(Request $request, Closure $next)
    {
        $allowedDomains = [
            'https://mywebsite.com', // 你的前端域名
            'http://localhost:8080' // 本地开发域名按需添加
        ];
        $origin = $request->headers->get('Origin');
        $referer = $request->headers->get('Referer');
        
        foreach ($allowedDomains as $domain) {
            if (str_starts_with($origin, $domain) || str_starts_with($referer, $domain)) {
                return $next($request);
            }
        }
        abort(403);
    }
    
  • 第三步:注册中间件并绑定路由
    打开app/Http/Kernel.php,在$routeMiddleware数组里添加:
    'check.origin' => \App\Http\Middleware\CheckSameOrigin::class,
    
    调整你的路由代码:
    Route::get('MyFAQS',[\App\Http\Controllers\FaqController::class,'getQuestions'])->middleware('check.origin');
    

注意:该方案无法防御伪造来源的恶意请求,仅能拦截普通的直接访问

方案2:Laravel签名路由(推荐,安全性高)

利用Laravel自带的签名路由机制,生成带有效期的加密访问链接,第三方无权限生成合法链接:

  • 第一步:给路由添加签名中间件和路由名
    Route::get('MyFAQS',[\App\Http\Controllers\FaqController::class,'getQuestions'])
        ->name('faq.questions')
        ->middleware('signed');
    
  • 第二步:在前端入口Blade模板中注入签名链接
    打开你的Vue入口对应的blade文件,在head标签中添加meta标签:
    <meta name="faq_api_url" content="{{ URL::temporarySignedRoute('faq.questions', now()->addMinutes(30)) }}">
    
    这里设置了签名30分钟过期,可根据需求调整有效期。
  • 第三步:调整前端请求逻辑,读取签名链接调用
    const faqApiUrl = document.querySelector('meta[name="faq_api_url"]').content;
    axios.get(faqApiUrl)
    .then(response => {
        this.FAQ = response.data;
        console.log(this.FAQ);
    })
    .catch(error=>{
        console.log("can not get FAQ: " + error)
    })
    

该方案基本可以拦截99%的恶意爬取,就算第三方拿到过期的签名链接也无法正常访问。

方案3:自定义加密签名校验(适合高安全要求场景)

前后端约定加密规则,动态生成请求校验标识,拦截无有效标识的请求:

  • 第一步:前端添加请求拦截器,生成加密签名
    可借助js-md5库实现加密,代码示例:
    import md5 from 'js-md5';
    // 密钥请存在前端环境变量中,不要硬编码
    const API_SECRET = import.meta.env.VITE_API_SIGN_SECRET;
    
    axios.interceptors.request.use(config => {
      const timestamp = Math.floor(Date.now() / 1000);
      // 加密规则可自行调整,只要前后端一致即可
      const sign = md5(`${timestamp}${API_SECRET}MyFAQS`);
      config.headers['X-REQ-SIGN'] = sign;
      config.headers['X-REQ-TIME'] = timestamp;
      return config;
    })
    
  • 第二步:后端生成校验中间件,验证签名合法性
    中间件逻辑示例:
    public function handle(Request $request, Closure $next)
    {
        $sign = $request->header('X-REQ-SIGN');
        $timestamp = $request->header('X-REQ-TIME');
        $apiSecret = config('app.api_sign_secret'); // 密钥存在.env配置中
    
        // 校验时间差,防止重放攻击,这里设置5分钟内的请求有效
        if (abs(time() - $timestamp) > 300 || !$sign) {
            abort(403);
        }
        // 校验签名是否一致
        if (md5($timestamp . $apiSecret . 'MyFAQS') !== $sign) {
            abort(403);
        }
        return $next($request);
    }
    
    最后把中间件绑定到对应路由即可。

兜底优化:添加频率限制

不管使用哪种方案,都可以给路由添加Laravel自带的频率限制中间件,避免被批量爬取:

Route::get('MyFAQS',[\App\Http\Controllers\FaqController::class,'getQuestions'])
    ->middleware('throttle:60,1'); // 每分钟最多允许60次请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 11:06:03