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

配置Laravel Passport后,如何允许自有网站未登录用户访问API?

解决方案:限制API仅允许自有网站访问(无论用户是否登录)

嘿,这个需求我之前也碰到过,咱们可以通过自定义中间件来实现,替换掉原来的auth:api中间件逻辑,既允许未登录用户访问,又能挡住非自有网站的请求。

步骤1:创建自定义验证中间件

首先生成一个专门验证请求来源的中间件:

php artisan make:middleware VerifyOwnWebsite

步骤2:编写中间件验证逻辑

打开生成的app/Http/Middleware/VerifyOwnWebsite.php,替换成下面的代码,这里提供两种验证方式,你可以根据需求选一种(或者结合使用更安全):

方式一:通过Referer头验证域名

这种方式适合纯网页端的请求,检查请求的来源域名是否是你的自有网站:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class VerifyOwnWebsite
{
    public function handle(Request $request, Closure $next): Response
    {
        // 这里替换成你的自有网站域名,多个的话用数组
        $allowedDomains = ['your-domain.com', 'www.your-domain.com'];
        
        // 获取请求的Referer头
        $referer = $request->headers->get('Referer');
        if (!$referer) {
            return response()->json(['message' => 'Unauthorized access'], 403);
        }
        
        // 解析Referer提取域名
        $parsedUrl = parse_url($referer);
        $domain = $parsedUrl['host'] ?? '';
        
        // 验证域名是否在允许列表内
        if (!in_array($domain, $allowedDomains)) {
            return response()->json(['message' => 'Unauthorized access'], 403);
        }
        
        // 验证通过,继续处理请求
        return $next($request);
    }
}

方式二:通过自定义请求头验证(更安全)

如果担心Referer头可能被篡改或缺失,可以用自定义密钥的方式,让前端请求时带上专属头:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class VerifyOwnWebsite
{
    public function handle(Request $request, Closure $next): Response
    {
        // 从请求头获取自定义密钥,和.env里的配置对比
        $requestSecret = $request->headers->get('X-OWN-WEBSITE-SECRET');
        if ($requestSecret !== env('OWN_WEBSITE_SECRET')) {
            return response()->json(['message' => 'Unauthorized access'], 403);
        }
        
        return $next($request);
    }
}

然后在你的.env文件里添加一个随机的密钥:

OWN_WEBSITE_SECRET=your-random-secret-string-here

同时要确保你的前端在所有API请求里都带上X-OWN-WEBSITE-SECRET这个请求头,值就是上面配置的密钥。

步骤3:注册中间件

打开app/Http/Kernel.php,在$routeMiddleware数组里添加我们的自定义中间件:

protected $routeMiddleware = [
    // ... 其他中间件
    'verify.own.website' => \App\Http\Middleware\VerifyOwnWebsite::class,
];

步骤4:更新路由配置

最后修改路由服务提供者里的mapApiRoutes方法,把原来的auth:api中间件换成我们的自定义中间件:

protected function mapApiRoutes() {
    Route::prefix('api')
         ->middleware('verify.own.website')
         ->namespace($this->namespace)
         ->group(base_path('routes/api.php'));
}

补充说明

如果你的API需要区分登录用户和未登录用户的权限(比如登录用户能访问更多接口),可以同时保留auth:api中间件,但设置为可选:

// 路由里单独给需要登录的接口加auth:api
// 比如在routes/api.php里
Route::get('/public-data', [YourController::class, 'publicData']); // 不需要登录,只要是自有网站就能访问
Route::get('/user-data', [YourController::class, 'userData'])->middleware('auth:api'); // 需要登录+自有网站

这样设置后,只有来自你自有网站的请求(不管用户是否登录)才能访问API,其他第三方客户端的请求会被直接拒绝~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:29:33