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

Laravel 8 基于Passport的SSO实现如何完成子应用API路由授权

SSO子应用API鉴权优化方案

核心结论

不需要每次调用子应用API时都请求sso-app验证token有效性,基于JWT的特性可实现本地校验,性能最优,无额外网络开销。

最优实现方案:子应用本地校验JWT签名

你使用的Laravel Passport默认生成的Access Token是标准JWT格式,本身具备自包含、可验签的特性,仅需通过sso-app的公钥即可在子应用本地完成合法性校验,步骤如下:

  • 从sso-app的storage/oauth-public.key文件中获取公钥,将公钥文件部署到所有子应用的服务器存储目录中,不要提交到代码仓库,和其他敏感配置统一管理
  • 子应用自定义API鉴权中间件,完成以下逻辑:
    1. 从请求头Authorization中提取Bearer Token
    2. 用sso公钥校验JWT签名,确认token未被篡改
    3. 校验JWT内置的过期时间exp,确认token在有效期内
    4. 解析JWT payload中的用户信息,和子应用本地用户表关联,完成身份认证
  • 将自定义中间件注册到子应用的API路由组即可生效

中间件示例代码(Laravel框架)

<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\ValidationData;

class SSOAPIAuth
{
    public function handle(Request $request, Closure $next)
    {
        $token = $request->bearerToken();
        if (!$token) {
            return response()->json(['message' => '未授权访问'], 401);
        }

        try {
            // 解析JWT token
            $jwt = (new Parser())->parse($token);
            // 加载SSO公钥
            $publicKey = file_get_contents(storage_path('sso-oauth-public.key'));
            // 校验签名合法性
            if (!$jwt->verify(new Sha256(), $publicKey)) {
                return response()->json(['message' => '无效的访问凭证'], 401);
            }
            // 校验token有效期
            $validationData = new ValidationData();
            if (!$jwt->validate($validationData)) {
                return response()->json(['message' => '访问凭证已过期'], 401);
            }
            // 关联本地用户
            $userInfo = $jwt->claims()->get('user');
            $user = \App\Models\User::where('email', $userInfo->email)->firstOrFail();
            auth()->setUser($user);
        } catch (\Throwable $e) {
            return response()->json(['message' => '访问凭证校验失败'], 401);
        }

        return $next($request);
    }
}

注册中间件到app/Http/Kernel.php的$routeMiddleware数组:

protected $routeMiddleware = [
    // 其他中间件
    'sso.api.auth' => \App\Http\Middleware\SSOAPIAuth::class,
];

在API路由中使用:

Route::group(['middleware' => 'sso.api.auth'], function () {
    // 需要鉴权的API接口
});

特殊场景优化:需实时校验token吊销的情况

如果你的业务要求用户踢下线、权限变更时token要立即失效,可在本地校验的基础上增加缓存层,无需每次请求sso-app:

  • sso-app和所有子应用共用Redis缓存实例,token签发时将token的唯一标识存入Redis,过期时间和token本身的exp一致
  • 子应用中间件完成本地JWT校验后,增加一步Redis查询,确认token未被吊销即可放行
  • sso-app触发token吊销操作时,直接将对应token从Redis中删除即可,所有子应用会实时生效

该方案仅增加一次本地Redis查询,开销极低,同时满足实时性要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:45:04