Laravel 10集成Auth0登录:仅允许Auth0凭证/OTP登录实现指导
Laravel 10 集成Auth0自定义登录方案(匹配你的需求)
1. Auth0控制台配置
- 开启应用的Password Grant:进入应用「Advanced Settings」→「Grant Types」,勾选「Password」选项
- 启用MFA(如需OTP登录):在「Authentication」→「MFA」中开启OTP验证方式
- 关闭自助注册:在「Authentication」→「Database」里禁用「Allow Sign Ups」
- 创建Management API Token:需包含
create:users权限,用于同步Laravel用户到Auth0
2. 自定义登录逻辑(先验本地用户,再走Auth0验证)
修改app/Http/Controllers/Auth/LoginController.php,重写登录方法,跳过本地密码验证,优先校验本地用户状态:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; use App\Models\User; public function login(Request $request) { $request->validate([ 'email' => 'required|email', 'password' => 'required_without:otp', 'otp' => 'required_without:password', ]); // 第一步:校验本地活跃用户 $localUser = User::where('email', $request->email)->where('active', true)->first(); if (!$localUser) { return back()->withErrors(['email' => '用户不存在或未激活']); } // 第二步:调用Auth0 API验证凭证 $auth0Config = config('auth0'); $tokenEndpoint = "https://{$auth0Config['domain']}/oauth/token"; $payload = [ 'client_id' => $auth0Config['client_id'], 'client_secret' => $auth0Config['client_secret'], 'audience' => "https://{$auth0Config['domain']}/api/v2/", 'username' => $request->email, ]; if ($request->filled('password')) { $payload['grant_type'] = 'password'; $payload['password'] = $request->password; $payload['scope'] = 'openid profile email'; } else { $payload['grant_type'] = 'http://auth0.com/oauth/grant-type/mfa-otp'; $payload['otp'] = $request->otp; $payload['mfa_token'] = session('auth0_mfa_token'); } $response = Http::post($tokenEndpoint, $payload); if ($response->failed()) { $errorMsg = $response->json()['error_description'] ?? '登录验证失败'; // 处理MFA触发场景,跳转OTP输入界面 if ($response->json()['error'] === 'mfa_required') { session(['auth0_mfa_token' => $response->json()['mfa_token']]); return back()->with('requires_otp', true)->withInput($request->only('email')); } return back()->withErrors(['email' => $errorMsg]); } // 验证通过,登录本地用户 auth()->login($localUser); return redirect()->intended('/dashboard'); }
更新登录视图resources/views/auth/login.blade.php,添加OTP输入区域:
<form method="POST" action="{{ route('login') }}"> @csrf <div class="mb-3"> <label for="email" class="form-label">邮箱</label> <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus> @error('email') <div class="text-danger mt-1">{{ $message }}</div> @enderror </div> <!-- 密码输入框 --> <div id="password-section" class="mb-3 {{ session('requires_otp') ? 'd-none' : '' }}"> <label for="password" class="form-label">密码</label> <input id="password" type="password" class="form-control" name="password" required> </div> <!-- OTP输入框 --> <div id="otp-section" class="mb-3 {{ session('requires_otp') ? '' : 'd-none' }}"> <label for="otp" class="form-label">一次性密码(OTP)</label> <input id="otp" type="text" class="form-control" name="otp" {{ session('requires_otp') ? 'required' : '' }}> </div> <button type="submit" class="btn btn-primary">登录</button> </form>
3. Laravel用户创建同步到Auth0
在User模型中添加创建事件,自动同步用户到Auth0:
use Illuminate\Support\Facades\Http; use Illuminate\Support\Str; protected static function booted() { parent::booted(); static::created(function ($user) { $auth0Config = config('auth0'); $managementEndpoint = "https://{$auth0Config['domain']}/api/v2/users"; // 生成临时密码(可后续引导用户重置) $tempPassword = Str::random(12); $response = Http::withToken($auth0Config['management_token']) ->post($managementEndpoint, [ 'email' => $user->email, 'password' => $tempPassword, 'email_verified' => true, 'connection' => 'Username-Password-Authentication', // 你的Auth0数据库连接名 'app_metadata' => [ 'local_user_id' => $user->id, 'organization_id' => $user->organization_id, ], ]); if ($response->failed()) { \Log::critical('Auth0用户同步失败', [ 'local_user_id' => $user->id, 'auth0_response' => $response->body() ]); // 可选:抛出异常回滚用户创建 // throw new \RuntimeException('用户创建失败,请重试'); } // 可选:发送临时密码给用户 // Mail::to($user->email)->send(new TempPasswordMail($tempPassword)); }); }
4. 禁用本地登录冗余功能
- 删除Laravel默认的注册路由(若存在),确保用户只能通过你的权限控制接口创建
- 若不需要本地密码重置,可删除密码重置相关路由和控制器
- 确保
config/auth.php中默认guard的认证逻辑完全使用上述自定义流程
5. 保留Spatie Permissions原有流程
权限、组织信息均存储在本地数据库,登录成功后直接沿用现有Spatie权限校验逻辑即可,无需额外修改。
内容的提问来源于stack exchange,提问作者Lokesh M
相关产品推荐
相关产品推荐

