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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 12:27:04