Laravel Socialite第三方登录新增前置密码验证步骤的实现咨询
实现方案
整体流程调整:原有回调逻辑不再直接完成登录,改为先临时存储第三方授权通过的用户标识,跳转至密码校验页,校验通过后再执行本站登录操作。
步骤1:修改第三方登录回调方法
替换原有直接登录的逻辑,增加临时会话存储和跳转逻辑:
public function callback(Request $request, $provider, SocialAccountsService $service) { if ($request->has("error")) { return redirect()->route("website.index"); } try { $socialUser = Socialite::driver($provider)->user(); $user = $service->createOrGetUser($socialUser, $provider); // 临时存储第三方验证通过的用户信息,设置10分钟有效期 session()->put([ 'social_auth_valid' => true, 'social_auth_user_id' => $user->id, 'social_auth_provider' => $provider ])->expireAt(now()->addMinutes(10)); // 判断用户是否已设置本站密码,跳转对应页面 if (empty($user->password)) { // 首次用第三方登录的新用户,跳转至密码设置页 return redirect()->route('auth.social.set_password'); } else { // 已有账号的老用户,跳转至密码验证页 return redirect()->route('auth.social.verify_password'); } } catch (InvalidStateException $e) { Log::error($e->getMessage()); return redirect()->route("auth.register.index"); } }
步骤2:新增密码校验相关路由
在路由文件中添加以下路由,推荐加throttle中间件限制请求频率,防止暴力破解密码:
// 老用户密码验证页 Route::get('/social-auth/verify-password', [SocialAuthController::class, 'showVerifyPasswordForm'])->name('auth.social.verify_password')->middleware('throttle:5,1'); // 提交密码验证请求 Route::post('/social-auth/verify-password', [SocialAuthController::class, 'verifyPassword'])->name('auth.social.verify_password.submit')->middleware('throttle:5,1'); // 新用户密码设置页 Route::get('/social-auth/set-password', [SocialAuthController::class, 'showSetPasswordForm'])->name('auth.social.set_password')->middleware('throttle:5,1'); // 提交新密码设置请求 Route::post('/social-auth/set-password', [SocialAuthController::class, 'setPassword'])->name('auth.social.set_password.submit')->middleware('throttle:5,1');
步骤3:实现密码校验控制器方法
老用户密码验证逻辑
public function showVerifyPasswordForm(Request $request) { // 校验是否走了正常的第三方授权流程 if (!session()->get('social_auth_valid')) { return redirect()->route('auth.login.index')->withErrors('请先通过第三方平台授权'); } return view('auth.social_verify_password'); } public function verifyPassword(Request $request) { if (!session()->get('social_auth_valid')) { return redirect()->route('auth.login.index')->withErrors('请先通过第三方平台授权'); } $validated = $request->validate([ 'password' => 'required|string' ]); $user = User::findOrFail(session()->get('social_auth_user_id')); // 校验密码是否匹配 if (!Hash::check($validated['password'], $user->password)) { return back()->withErrors('密码输入错误,请重试'); } // 校验通过完成登录 auth()->login($user); // 清除临时会话数据避免复用 session()->forget(['social_auth_valid', 'social_auth_user_id', 'social_auth_provider']); return redirect()->route("dashboard.profile.index"); }
新用户密码设置逻辑(首次第三方登录场景)
public function showSetPasswordForm(Request $request) { if (!session()->get('social_auth_valid')) { return redirect()->route('auth.register.index')->withErrors('请先通过第三方平台授权'); } return view('auth.social_set_password'); } public function setPassword(Request $request) { if (!session()->get('social_auth_valid')) { return redirect()->route('auth.register.index')->withErrors('请先通过第三方平台授权'); } $validated = $request->validate([ 'password' => 'required|string|min:8|confirmed' ]); $user = User::findOrFail(session()->get('social_auth_user_id')); $user->password = Hash::make($validated['password']); $user->save(); auth()->login($user); session()->forget(['social_auth_valid', 'social_auth_user_id', 'social_auth_provider']); return redirect()->route("dashboard.profile.index"); }
步骤4:新增对应前端页面
分别开发密码输入页、密码设置页的表单,提交到对应路由即可,可在页面显示当前第三方登录的平台、关联邮箱等信息,降低用户误输概率。
可选优化点
- 临时会话有效期可根据业务需求调整,建议不超过15分钟
- 密码错误超过限制次数后可临时冻结该IP的验证请求,提升安全性
内容的提问来源于stack exchange,提问作者Yamin Ooh
相关产品推荐
相关产品推荐

