如何在两个Laravel应用间实现基于API的跨应用登录功能
跨Laravel应用API登录解决方案
现有代码问题分析
- 应用A中密码硬编码为固定值,未使用用户输入的真实凭证
- 应用B的API端点返回Web重定向,不符合API无状态设计(HTTP客户端无法处理重定向跳转)
- 应用B未验证请求来源合法性,存在恶意调用风险
- 应用B的参数验证缺少密码规则,且未验证用户数据库中的实际角色
- 应用A未处理API响应结果,未完成本地登录逻辑
完整实现步骤
1. 配置应用间身份密钥
在应用B的.env中添加应用身份验证密钥,用于识别合法的应用A请求:
APP_A_SECRET=your_secure_unique_secret_key_here
同时在应用A的.env中同步配置该密钥:
APP_B_SECRET=your_secure_unique_secret_key_here
2. 应用A:修正登录路由
接收用户输入的凭证,调用应用B的验证API,并处理响应完成本地登录:
Route::post('/api-login', function(){ // 获取用户提交的登录信息 $email = request('email'); $password = request('password'); $role = "Administrator"; // 可根据业务需求改为用户选择或动态获取 // 构造请求数据,包含应用身份密钥 $requestData = [ 'email' => $email, 'role' => $role, 'password' => $password, 'app_secret' => env('APP_B_SECRET') ]; // 调用应用B的验证API $response = Http::retry(3, 2000)->post('http://127.0.0.1:8000/api/login/validate', $requestData); // 处理API响应 if ($response->successful()) { $responseData = $response->json(); // 方案1:如果应用A有本地用户系统,创建/查找用户并完成本地登录 // $user = \App\Models\User::firstOrCreate( // ['email' => $email], // ['name' => $responseData['user']['name']] // ); // Auth::login($user); // 方案2:存储应用B的API Token,供后续跨应用操作使用 session(['app_b_token' => $responseData['token']]); return redirect()->route('home')->with('success', '跨应用登录成功'); } else { $errorMsg = $response->json('Message', '登录验证失败'); return back()->withErrors(['login' => $errorMsg]); } })->name('ApiLogin');
3. 应用B:修正API验证端点
实现应用身份验证、用户凭证验证,并返回标准JSON响应:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Validator; Route::post('/login/validate', function(Request $request){ // 第一步:验证应用身份合法性 if ($request->input('app_secret') !== env('APP_A_SECRET')) { return response()->json([ 'status' => 403, 'Message' => '非法应用请求' ], 403); } // 第二步:验证请求参数完整性 $validationRules = [ 'email' => 'email|required|max:300', 'role' => 'required|max:300', 'password' => 'required|min:6' ]; $validator = Validator::make($request->all(), $validationRules); if ($validator->fails()) { return response()->json([ 'status' => 422, 'Message' => '参数验证失败', 'errors' => $validator->errors() ], 422); } // 第三步:验证用户凭证与角色 $credentials = $request->only('email', 'password'); $requestedRole = $request->input('role'); if (!Auth::attempt($credentials)) { return response()->json([ 'status' => 401, 'Message' => '邮箱或密码错误' ], 401); } $user = Auth::user(); // 验证用户数据库中的实际角色是否匹配请求角色(假设用户模型有role字段) if ($user->role !== $requestedRole) { Auth::logout(); return response()->json([ 'status' => 401, 'Message' => '用户角色不匹配' ], 401); } // 第四步:生成API Token $token = $user->createToken('app_a_access_token')->plainTextToken; // 返回标准JSON响应 return response()->json([ 'status' => 200, 'Message' => '验证成功', 'user' => [ 'id' => $user->id, 'name' => $user->name, 'email' => $user->email ], 'token' => $token, 'token_type' => 'Bearer' ]); });
关键注意事项
- 跨域配置:若应用A与应用B域名不同,需在应用B中配置CORS规则,允许应用A的域名访问(可使用
laravel-cors包或手动修改config/cors.php) - Token管理:应用A存储的应用B Token需定期刷新,避免过期失效
- 安全加固:生产环境需使用HTTPS传输,防止凭证泄露
- 角色逻辑:若角色为多角色或动态分配,需调整角色验证逻辑,避免硬编码判断
内容的提问来源于stack exchange,提问作者Prince Asamoah
相关产品推荐
相关产品推荐

