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

Laravel多项目单点登录:使用独立SQL Server统一认证

多Laravel项目单点登录(SSO)实现方案

针对你的需求——5个独立部署、各带自有SQL数据库的Laravel项目,通过第6个独立SQL Server完成一次登录即可访问所有项目,同时保留各项目自身数据库运行——以下是基于Laravel生态的落地实现方案:

核心思路

用一个全新的Laravel项目作为SSO认证中心(连接第6个SQL Server),负责统一的用户登录验证与Token发放;5个现有项目通过对接该认证中心验证Token有效性,同时保留自身数据库的业务数据存储与逻辑。这里选用laravel/passport来实现,因为它贴合Laravel生态,能快速完成OAuth2.0协议的落地。


步骤1:搭建SSO认证中心

1.1 初始化认证中心项目

创建新Laravel项目,配置.env连接到你的第6个独立SQL Server。

1.2 配置Laravel Passport

  1. 安装依赖包:
    composer require laravel/passport
    
  2. 执行数据库迁移(创建Passport所需的Token、客户端表):
    php artisan migrate
    
  3. 生成Passport加密密钥:
    php artisan passport:install
    
  4. 在User模型中引入Passport的Trait:
    namespace App\Models;
    
    use Illuminate\Foundation\Auth\User as Authenticatable;
    use Laravel\Passport\HasApiTokens;
    use Illuminate\Notifications\Notifiable;
    
    class User extends Authenticatable
    {
        use HasApiTokens, Notifiable;
    
        protected $fillable = ['name', 'email', 'password'];
    }
    
  5. 在AuthServiceProvider的boot方法中注册Passport路由:
    namespace App\Providers;
    
    use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
    use Laravel\Passport\Passport;
    
    class AuthServiceProvider extends ServiceProvider
    {
        protected $policies = [];
    
        public function boot()
        {
            $this->registerPolicies();
            Passport::routes();
            // 设置Token有效期,按需调整
            Passport::tokensExpireIn(now()->addDays(30));
        }
    }
    
  6. 修改config/auth.php,将API guard的驱动改为passport:
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],
    
  7. 创建一个/api/user接口,用于返回当前登录用户信息(供其他项目验证Token时调用):
    Route::middleware('auth:api')->get('/user', function (Request $request) {
        return $request->user();
    });
    

步骤2:配置5个现有Laravel项目

每个项目都需要对接认证中心,实现Token验证与登录状态同步。

2.1 基础配置

  1. 安装laravel/passport(无需执行迁移和passport:install):
    composer require laravel/passport
    
  2. 在config/services.php中添加认证中心的配置:
    'sso' => [
        'client_id' => env('SSO_CLIENT_ID'),
        'client_secret' => env('SSO_CLIENT_SECRET'),
        'auth_url' => env('SSO_AUTH_URL'), // 比如https://example.com/sso
        'user_info_url' => env('SSO_AUTH_URL').'/api/user',
        'token_url' => env('SSO_AUTH_URL').'/oauth/token',
    ],
    
  3. 在项目.env中填入对应值(从认证中心的oauth_clients表获取客户端ID和密钥):
    SSO_CLIENT_ID=认证中心的客户端ID
    SSO_CLIENT_SECRET=认证中心的客户端密钥
    SSO_AUTH_URL=https://example.com/sso
    

2.2 实现Token验证中间件

创建一个中间件,用于向认证中心验证请求携带的Token有效性:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Http;

class VerifySsoToken
{
    public function handle($request, Closure $next)
    {
        $token = $request->bearerToken() ?? session('sso_token');
        
        if (!$token) {
            return redirect()->to(env('SSO_AUTH_URL').'/login?redirect='.urlencode(url()->current()));
        }

        // 向认证中心验证Token
        $response = Http::withToken($token)->get(config('services.sso.user_info_url'));
        if ($response->failed()) {
            session()->forget('sso_token');
            return redirect()->to(env('SSO_AUTH_URL').'/login?redirect='.urlencode(url()->current()));
        }

        // 将认证中心返回的用户信息注入请求
        $request->attributes->set('sso_user', $response->json());
        
        // 可选:关联本地用户(如果项目需要本地用户记录)
        $this->syncLocalUser($response->json());

        return $next($request);
    }

    private function syncLocalUser(array $ssoUser)
    {
        // 首次登录时自动创建本地用户,关联sso用户ID
        \App\Models\User::firstOrCreate(
            ['sso_user_id' => $ssoUser['id']],
            ['name' => $ssoUser['name'], 'email' => $ssoUser['email']]
        );
    }
}

在app/Http/Kernel.php中注册该中间件:

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

2.3 处理登录跳转与回调

  1. 替换原有登录页面的登录按钮,跳转到认证中心:
    <a href="{{ env('SSO_AUTH_URL') }}/login?redirect={{ urlencode(url()->current()) }}">统一登录</a>
    
  2. 在认证中心的登录逻辑中,登录成功后生成Token,跳回原项目的回调路由:
    // 认证中心的登录控制器
    public function login(Request $request)
    {
        // 验证用户 credentials
        if (Auth::attempt($request->only('email', 'password'))) {
            $user = Auth::user();
            $token = $user->createToken('SSO Token')->accessToken;
            // 跳回原项目,携带Token
            return redirect()->to($request->redirect.'?token='.$token);
        }
        // 登录失败逻辑
    }
    
  3. 在每个现有项目中添加回调路由,存储Token到Session:
    Route::get('/sso/callback', function (Request $request) {
        session(['sso_token' => $request->token]);
        return redirect($request->redirect);
    });
    

2.4 全局注入Token

创建中间件,自动将Session中的Token注入请求头,避免手动携带:

namespace App\Http\Middleware;

use Closure;

class InjectSsoToken
{
    public function handle($request, Closure $next)
    {
        if (session()->has('sso_token')) {
            $request->headers->set('Authorization', 'Bearer '.session('sso_token'));
        }
        return $next($request);
    }
}

在Kernel.php的web中间件组中添加该中间件:

protected $middlewareGroups = [
    'web' => [
        // ... 原有中间件
        \App\Http\Middleware\InjectSsoToken::class,
    ],
];

步骤3:保留项目数据库独立性

所有项目的业务模型(如订单、内容等)依然使用自身的SQL数据库,仅在用户认证环节依赖SSO认证中心。如果需要将业务数据与用户关联,可通过本地用户表的sso_user_id字段关联认证中心的用户ID,如步骤2.2中的syncLocalUser方法所示。


注意事项

  • 所有项目必须使用HTTPS协议,避免Token明文传输。
  • 可根据需求调整Token有效期,或添加Token自动刷新逻辑。
  • 认证中心需做好权限控制,确保只有信任的项目能获取Token。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 08:15:42