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

Laravel8集成LDAPRecord认证后Auth::user()跨请求返回null

问题原因

你遇到的登录态无法跨请求持久化问题,由3个核心错误导致:

  • 错误使用shouldUse()方法做动态guard切换:shouldUse()仅会修改当前请求生命周期内的默认guard,不会将当前认证使用的guard标识持久化到session。两个自定义guardpio和voj的session认证存储键是互相隔离的,如果你通过vojguard认证成功,下一个请求Laravel会默认加载配置文件中写死的pioguard读取认证数据,自然无法获取登录态;即使是pioguard登录的场景,缺少LDAP唯一标识同步也会导致认证失效。
  • 未配置LDAP唯一标识(GUID)同步:LDAP Record的数据库认证驱动要求必须在本地users表存储AD用户的唯一objectguid字段,作为本地数据库用户和LDAP用户的绑定依据。你当前的同步规则仅同步了邮箱、姓名字段,当前请求中因刚完成LDAP查询可以返回完整用户模型,但跨请求时guard从session取出本地用户ID后,无法通过GUID匹配到对应LDAP用户实例,会直接返回null。
  • 认证逻辑存在细节缺陷:构造voj域登录凭证时仍使用@pio.rs邮箱后缀,会导致所有voj域用户认证失败;remember参数的判断逻辑冗余,没有使用Laravel内置的参数取值方法。
修复步骤
  1. 新增本地用户表GUID字段
    新建数据库迁移,为users表添加存储LDAP唯一标识的字段:

    Schema::table('users', function (Blueprint $table) {
        $table->string('guid', 64)->unique()->after('id');
    });
    

    执行迁移php artisan migrate完成字段添加。

  2. 修改模型和认证提供者配置
    首先在App\Models\User模型中添加属性,指定LDAP关联字段:

    protected $guidKey = 'guid';
    

    然后修改config/auth.php中两个LDAP提供者的同步规则,加入GUID字段同步:

    'sync_attributes' => [
        'guid' => 'objectguid', // 新增AD唯一标识同步
        'email' => 'mail',
        'name' => 'cn',
    ],
    

    两个提供者的配置都需要加这一行。

  3. 修复登录控制器逻辑
    调整登录认证代码,认证成功后将当前使用的guard标识存入session,同时修正voj域的邮箱后缀、简化remember参数取值:

    public function store(Request $request)  {
        $remember = $request->boolean('remember');
        
        // 尝试pio域认证
        $pioCredentials = [
            'mail' => $request->input('username').'@pio.rs',
            'password' => $request->input('password'),
        ];
        auth()->shouldUse('pio');
        if (auth()->attempt($pioCredentials, $remember)) {
            session(['auth_guard' => 'pio']);
            return redirect()->route('home');
        }
    
        // 尝试voj域认证,替换为你voj域实际的邮箱后缀
        $vojCredentials = [
            'mail' => $request->input('username').'@voj.rs',
            'password' => $request->input('password'),
        ];
        auth()->shouldUse('voj');
        if (auth()->attempt($vojCredentials, $remember)) {
            session(['auth_guard' => 'voj']);
            return redirect()->route('home');
        }
    
        return back()->withErrors(['username' => '账号或密码错误']);
    }
    

    记得把@voj.rs替换成你vojAD域实际使用的邮箱后缀。

  4. 添加全局guard判断逻辑
    打开app/Http/Kernel.php,在web中间件组的StartSession中间件之后添加一段闭包中间件,保证每个请求启动时自动加载session中存储的guard标识:

    protected $middlewareGroups = [
        'web' => [
            // 原有其他中间件保持不变
            \Illuminate\Session\Middleware\StartSession::class,
            // 新增以下代码
            function ($request, $next) {
                if (session()->has('auth_guard')) {
                    auth()->shouldUse(session('auth_guard'));
                }
                return $next($request);
            },
            // 原有其他中间件保持不变
        ],
    ];
    
  5. 补充登出逻辑
    在登出方法中清除session中存储的guard标识,避免后续登录逻辑异常:

    public function logout()
    {
        auth()->logout();
        session()->forget('auth_guard');
        return redirect()->route('login');
    }
    
验证操作

完成所有修改后,依次执行以下命令清除缓存:

php artisan config:clear
php artisan route:clear
php artisan cache:clear

清除浏览器本地存储的所有站点Cookie后重新登录,即可正常跨请求保持登录状态。

内容的提问来源于stack exchange,提问作者n_ivkovic021

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 03:51:26