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

Laravel 5自定义Auth登录:支持userName或loginName登录

嘿,这个需求其实挺常见的,我给你两种靠谱的实现方案,你可以根据项目的实际情况来选择:

方案1:直接查询验证(快速上手)

这种方式不需要改动Laravel的默认认证体系,直接手动查询用户再验证密码,逻辑清晰好理解:

// 获取用户输入的登录标识(可能是userName或loginName)
$loginIdentifier = $request->userName;
$password = $request->passHash;

// 查找匹配的用户:要么userName匹配,要么loginName匹配且loginName不为空
$user = \App\Models\User::where('userName', $loginIdentifier)
    ->orWhere(function ($query) use ($loginIdentifier) {
        $query->where('loginName', $loginIdentifier)
              ->whereNotNull('loginName');
    })
    ->first();

// 验证用户是否存在且密码正确
if ($user && \Illuminate\Support\Facades\Hash::check($password, $user->password)) {
    // 手动登录用户
    \Illuminate\Support\Facades\Auth::login($user);
    
    // 这里写登录成功后的逻辑,比如跳转仪表盘
    return redirect()->intended('/dashboard');
} else {
    // 认证失败,返回错误提示
    return back()->withErrors(['userName' => '用户名或密码错误']);
}

注意:一定要加上whereNotNull('loginName')这个条件,避免匹配到那些还没设置loginName的用户(他们的loginName字段是NULL),防止出现不必要的匹配冲突。

方案2:自定义认证逻辑(优雅适配Laravel体系)

如果你希望继续使用Auth::attempt()的写法,保持代码风格一致,可以自定义用户认证的查询逻辑。这里提供两种实现方式:

方式A:在User模型中添加范围查询

在你的User模型里定义一个范围查询方法,封装匹配逻辑,让代码更简洁:

// 在User模型中添加范围查询
public function scopeByLoginIdentifier($query, $identifier)
{
    return $query->where('userName', $identifier)
        ->orWhere(function ($q) use ($identifier) {
            $q->where('loginName', $identifier)
              ->whereNotNull('loginName');
        });
}

// 然后在认证代码里调用:
$user = \App\Models\User::byLoginIdentifier($request->userName)->first();
if ($user && \Illuminate\Support\Facades\Hash::check($request->passHash, $user->password)) {
    \Illuminate\Support\Facades\Auth::login($user);
    // ... 后续登录成功逻辑
}

方式B:扩展EloquentUserProvider(完全适配Auth::attempt)

如果你想完全沿用Auth::attempt()的写法,不改动原有调用逻辑,可以扩展Laravel默认的用户提供者:

  1. 创建自定义用户提供者类:
namespace App\Providers;

use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;

class CustomUserProvider extends EloquentUserProvider
{
    public function retrieveByCredentials(array $credentials)
    {
        if (empty($credentials) ||
           (count($credentials) === 1 &&
            array_key_exists('password', $credentials))) {
            return;
        }

        // 获取登录标识
        $loginIdentifier = $credentials['userName'];
        unset($credentials['password']);

        // 构建匹配查询
        $query = $this->createModel()->newQuery();
        return $query->where('userName', $loginIdentifier)
            ->orWhere(function ($q) use ($loginIdentifier) {
                $q->where('loginName', $loginIdentifier)
                  ->whereNotNull('loginName');
            })
            ->first();
    }
}
  1. 在AuthServiceProvider的boot方法中注册这个提供者:
public function boot()
{
    $this->registerPolicies();

    \Illuminate\Support\Facades\Auth::provider('custom', function ($app, array $config) {
        return new CustomUserProvider($app['hash'], $config['model']);
    });
}
  1. 修改config/auth.php中的用户提供者配置:
'providers' => [
    'users' => [
        'driver' => 'custom', // 替换为自定义的驱动名
        'model' => App\Models\User::class,
    ],
],

完成后,你就可以继续使用原来的Auth::attempt()代码了,它会自动用我们的自定义逻辑查找用户:

if (Auth::attempt(['userName' => $request->userName, 'password' => $request->passHash])) {
    // 登录成功后的逻辑
}

两种方案各有优劣:方案1快速简单,适合小项目或临时需求;方案2更符合Laravel的设计规范,适合需要长期维护的大型项目。你可以根据自己的情况选择~

内容的提问来源于stack exchange,提问作者Nicholas Déziel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:05:01