Laravel跨项目API身份认证实现:求相关教程指引
实现两个Laravel项目的API身份认证互通
这是多项目体系里非常常见的需求,我之前在团队内的多个Laravel项目中实现过类似的互通,给你整理了几个可落地的方案,每个方案都有具体的操作步骤,你可以根据自己的项目场景选择:
方案1:基于OAuth2的标准互通方案(推荐用于独立部署的项目)
这种方式把其中一个项目作为认证服务器,另一个作为客户端应用,遵循OAuth2协议实现跨项目认证,是最规范、扩展性最强的方案。
步骤1:配置认证服务器(项目A)
我们用Laravel官方的Passport包来实现OAuth2服务:
- 安装Passport:
composer require laravel/passport - 运行数据库迁移,创建Passport需要的表:
php artisan migrate - 生成加密密钥和客户端凭证:
php artisan passport:install - 在
App\Models\User模型中添加HasApiTokenstrait,让用户支持API令牌:use Laravel\Passport\HasApiTokens; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; // ... 其他代码 } - 在
App\Providers\AuthServiceProvider的boot方法中注册Passport路由:use Laravel\Passport\Passport; public function boot() { $this->registerPolicies(); Passport::routes(); // 可以设置令牌有效期,比如30天 Passport::tokensExpireIn(now()->addDays(30)); } - 修改
config/auth.php,把API认证的驱动改为passport:'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
步骤2:配置客户端项目(项目B)
项目B需要通过OAuth2协议向项目A验证用户身份:
- 同样安装Laravel Passport:
composer require laravel/passport - 在项目A的后台(或者通过
php artisan passport:client命令)创建一个密码授权客户端,记录下生成的client_id和client_secret。 - 在项目B的
.env文件中添加认证服务器的配置:PASSPORT_CLIENT_ID=你的client_id PASSPORT_CLIENT_SECRET=你的client_secret PASSPORT_AUTH_SERVER_URL=http://项目A的域名/api - 创建一个自定义的认证逻辑,比如在项目B的
AuthController中添加方法,接收用户的账号密码,调用项目A的API验证并获取令牌:public function login(Request $request) { $response = Http::post(config('app.passport_auth_server_url').'/oauth/token', [ 'grant_type' => 'password', 'client_id' => config('app.passport_client_id'), 'client_secret' => config('app.passport_client_secret'), 'username' => $request->email, 'password' => $request->password, 'scope' => '', ]); if ($response->successful()) { // 验证成功,可以在项目B中创建本地用户(如果需要),或者直接返回令牌给前端 $tokenData = $response->json(); // 可选:如果项目B需要本地用户记录,同步项目A的用户信息 $user = User::updateOrCreate( ['email' => $request->email], ['name' => $tokenData['user']['name']] // 假设项目A返回用户信息 ); // 生成项目B自己的令牌或者直接返回项目A的令牌 return response()->json($tokenData); } return response()->json(['message' => '认证失败'], 401); } - 前端拿到令牌后,请求项目B的API时,携带
Authorization: Bearer {token}头,项目B可以通过调用项目A的/api/user接口验证令牌有效性,确保认证的安全性。
方案2:共享JWT密钥的轻量方案(适合同体系的小型项目)
如果两个项目不需要严格的OAuth2流程,可以用JWT实现互通,核心是两个项目共享同一个JWT密钥,这样项目A生成的JWT令牌,项目B可以直接解析验证。
步骤1:在两个项目中安装JWT包
composer require tymon/jwt-auth
步骤2:共享JWT配置
- 在项目A中生成JWT密钥:
php artisan jwt:secret - 把项目A
.env中的JWT_SECRET复制到项目B的.env中,确保两个项目的JWT_SECRET完全一致。 - 两个项目的
config/auth.php都配置API驱动为jwt:'guards' => [ 'api' => [ 'driver' => 'jwt', 'provider' => 'users', ], ],
步骤3:实现互通逻辑
- 项目A的登录接口生成JWT令牌返回给前端。
- 前端拿着这个令牌请求项目B的API时,项目B的JWT认证中间件会自动验证令牌的有效性(因为密钥相同)。
- 注意:如果两个项目的用户数据库不共享,项目B需要通过API从项目A获取用户详情,或者在首次验证时同步用户信息到本地数据库。
方案3:共享数据库+会话驱动(适合同服务器/可共享数据库的项目)
如果两个项目可以共享数据库资源,这是最快捷的方案,用户在项目A登录后,会话会同步到项目B。
步骤1:共享用户数据库
把两个项目的.env中的数据库配置指向同一个数据库,至少共享users表(如果需要会话同步,还要共享sessions表,或者用Redis存储会话)。
步骤2:配置共享会话驱动
- 两个项目都安装Redis扩展:
composer require predis/predis - 修改
.env中的会话驱动和Redis配置:SESSION_DRIVER=redis REDIS_HOST=你的Redis地址 REDIS_PASSWORD=你的Redis密码(如果有) REDIS_PORT=6379 SESSION_DOMAIN=.yourdomain.com # 设置为主域名,比如两个项目是a.yourdomain.com和b.yourdomain.com - 这样用户在项目A登录后,会话会存储在Redis中,项目B读取同一个Redis的会话数据,就能直接识别已登录的用户。
注意事项
- 跨域问题:如果两个项目域名不同,需要配置CORS,Laravel可以用
fruitcake/laravel-cors包来解决。 - 安全性:无论用哪种方案,都要确保API请求用HTTPS传输,避免令牌被劫持。
- 用户信息同步:如果不共享数据库,要考虑用户信息更新后的同步问题,比如项目A修改了用户名,项目B也要同步更新。
内容的提问来源于stack exchange,提问作者Aminul Islam
相关产品推荐
相关产品推荐

