Laravel中如何让Auth::attempt支持pin等非password字段哈希校验
问题原因
Laravel 内置的用户认证提供者默认只会对password字段执行哈希校验逻辑,传入Auth::attempt的其他字段都会作为普通等值条件去数据库查询,所以你传入的明文pin会直接和数据库里的哈希值比对,自然永远匹配失败。
解决方案1:自定义认证提供者(长期稳定方案)
这个方案可以让Auth::attempt原生支持pin字段的哈希校验,不需要改动现有调用逻辑
- 第一步:创建自定义认证提供者类,重写凭据校验逻辑
<?php namespace App\Auth; use Illuminate\Auth\EloquentUserProvider; use Illuminate\Contracts\Auth\Authenticatable as UserContract; use Illuminate\Support\Facades\Hash; class CustomUserProvider extends EloquentUserProvider { public function validateCredentials(UserContract $user, array $credentials) { // 优先校验pin字段 if (isset($credentials['pin'])) { return Hash::check($credentials['pin'], $user->pin); } // 没有pin走默认的password校验逻辑 return parent::validateCredentials($user, $credentials); } }
- 第二步:注册自定义提供者,打开
app/Providers/AuthServiceProvider.php,在boot方法中添加代码:
public function boot() { $this->registerPolicies(); \Auth::provider('custom_eloquent', function ($app, $config) { return new CustomUserProvider($app['hash'], $config['model']); }); }
- 第三步:修改认证配置,打开
config/auth.php,修改providers部分的配置:
'providers' => [ 'users' => [ 'driver' => 'custom_eloquent', // 把原来的eloquent改成自定义的驱动名 'model' => App\Models\User::class, ], ],
配置完成后你原来的Auth::attempt(['empnik' => $empnik, 'pin' => "123456"])代码就可以正常生效了。
解决方案2:手动校验登录(轻量临时方案)
如果不想改动核心认证逻辑,可以自己先查询用户,手动校验pin后直接登录:
// 先根据empnik查询用户 $user = User::where('empnik', $empnik)->first(); if ($user && $user->pin && Hash::check($inputPin, $user->pin)) { // 校验通过直接登录 Auth::login($user); // 后续业务逻辑 }
注意事项
- 确保pin字段存储的是通过
Hash::make()方法生成的哈希值,不要直接存储明文 - 若需要同时支持password和pin两种校验方式,不要在
Auth::attempt的参数里同时传入password和pin两个字段
内容的提问来源于stack exchange,提问作者Eggy
相关产品推荐
相关产品推荐

