2023年7月27日发(作者:)
laravel修改⽤户模块的密码验证实现⽬录从配置⽂件⼊⼿使⽤Auth门⾯的attempt⽅法进⾏登录修改 Admin 模型⽂章参考做项⽬的时候,⽤户认证⼏乎是必不可少的,如果我们的项⽬由于⼀些原因不得不使⽤ users 之外的⽤户表进⾏认证,那么就需要多做⼀点⼯作来完成这个功能。现在假设我们只需要修改登录⽤户的表,表名和表结构都与框架默认的表users不同,⽂档没有教我们如何去做,但是别慌,稍微看下框架实现⽤户认证的源码就能轻松实现。⾸先,⾃定义⼀张表⽤来登录,表结构和模拟数据如下:表 adminsidlogin_name1adminlogin_pass2y10$2MUhp7b6ghVOngb/.b/x6uuEW/yL3FqPKJztawrM0U577Clf07xda从配置⽂件⼊⼿⽤户认证相关的配置都保存在config/⽂件中,先来看看配置⽂件的内容:
return [
/* |-------------------------------------------------------------------------- | Authentication Defaults |-------------------------------------------------------------------------- | | This option controls the default authentication "guard" and password | reset options for your application. You may change these defaults | as required, but they're a perfect start for most applications. | */
'defaults' => [ 'guard' => 'web', 'passwords' => 'users', ],
/* |-------------------------------------------------------------------------- | Authentication Guards |-------------------------------------------------------------------------- | | Next, you may define every authentication guard for your application. | Of course, a great default configuration has been defined for you | here which uses session storage and the Eloquent user provider. | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | Supported: "session", "token" | */
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ],
'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
/* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */
'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => AppUser::class, ],
// 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ],
/* |-------------------------------------------------------------------------- | Resetting Passwords |-------------------------------------------------------------------------- | | You may specify multiple password reset configurations if you have more | than one user table or model in the application and you want to have | separate password reset settings based on the specific user types. | | The expire time is the number of minutes that the reset token should be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | */
'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, ], ],
];默认使⽤的守卫是web,⽽web守卫使⽤的认证驱动是session,⽤户提供器是users。假设我们的需求只是将⽤户的提供器由users改为admins,那么我们需要做两步操作:修改默认的⽤户提供器,将provider=>'users'改为provider=>'admins' 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], ],配置admins提供器,假设依旧使⽤eloquent作为驱动,并创建好了admins表的模型 'providers' => [ 'admins' => [ 'driver' => 'eloquent', 'model' => AppAdmin::class ] ],使⽤Auth门⾯的attempt⽅法进⾏登录SessionGuard 中的attempt⽅法: //IlluminateAuthSessionGuard public function attempt(array $credentials = [], $remember = false) { $this->fireAttemptEvent($credentials, $remember);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider // to validate the user against the given credentials, and if they are in // fact valid we'll log the users into the application and return true. if ($this->hasValidCredentials($user, $credentials)) { $this->login($user, $remember);
return true; }
// If the authentication attempt fails we will fire an event so that the user // may be notified of any suspicious attempts to access their account from // an unrecognized user. A developer may listen to this event as needed. $this->fireFailedEvent($user, $credentials);
return false; }该⽅法中调⽤ UserProvider 接⼝的retrieveByCredentials⽅法检索⽤户,根据我们的配置,UserProvider接⼝的具体实现应该是EloquentUserProvider,因此,我们定位到EloquentUserProvider的retrieveByCredentials⽅法: //IlluminateAuthEloquentUserProvider public function retrieveByCredentials(array $credentials) { if (empty($credentials) || (count($credentials) === 1 && array_key_exists('password', $credentials))) { return; }
// First we will add each credential element to the query as a where clause. // Then we can execute the query and, if we found a user, return it in a // Eloquent User "model" that will be utilized by the Guard instances. $query = $this->createModel()->newQuery();
foreach ($credentials as $key => $value) { if (Str::contains($key, 'password')) { continue; }
if (is_array($value) || $value instanceof Arrayable) { $query->whereIn($key, $value); } else { $query->where($key, $value); } }
return $query->first(); }该⽅法会使⽤传⼊的参数(不包含password)到我们配置的数据表中搜索数据,查询到符合条件的数据之后返回对应的⽤户信息,然后attempt⽅法会进⾏密码校验,校验密码的⽅法为: //IlluminateAuthSessionGuard /** * Determine if the user matches the credentials. * * @param mixed $user * @param array $credentials * @return bool */ protected function hasValidCredentials($user, $credentials) { return ! is_null($user) && $this->provider->validateCredentials($user, $credentials); }进⼀步查看EloquentUserProvider中的validateCredentials⽅法 //IlluminateAuthEloquentUserProvider public function validateCredentials(UserContract $user, array $credentials) { $plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword()); }通过validateCredentials可以看出,提交的认证数据中密码字段名必须是password,这个⽆法⾃定义。同时可以看到,⼊参$user必须实现IlluminateContractsAuthAuthenticatable接⼝(UserContract是别名)。修改 Admin 模型Admin模型必须实现IlluminateContractsAuthAuthenticatable接⼝,可以借鉴⼀下User模型,让Admin直接继承IlluminateFoundationAuthUser 就可以,然后重写getAuthPassword⽅法,正确获取密码字段: // AppAdmin public function getAuthPassword() { return $this->login_pass; }不出意外的话,这个时候就能使⽤admins表进⾏登录了。Larval 5.4的默认Auth登陆传⼊邮件和⽤户密码到attempt ⽅法来认证,通过email 的值获取,如果⽤户被找到,经哈希运算后存储在数据中的password将会和传递过来的经哈希运算处理的passwrod值进⾏⽐较。如果两个经哈希运算的密码相匹配那么将会为这个⽤户开启⼀个认证Session。参考上⾯的分析,我们就需要对EloquentUserProvider中的validateCredentials⽅法进⾏重写,步骤如下1. 修改 添加如下代码 public function getAuthPassword() { return ['password' => $this->attributes['password'], 'salt' => $this->attributes['salt']]; }2. 建⽴⼀个⾃⼰的 的实现
namespace AppFoundationAuth;
use IlluminateAuthEloquentUserProvider; use IlluminateContractsAuthAuthenticatable; use IlluminateSupportStr;
/** * 重写⽤户密码校验逻辑 * Class GfzxEloquentUserProvider * @package AppFoundationAuth */ class GfzxEloquentUserProvider extends EloquentUserProvider { /** * Validate a user against the given credentials. * * @param IlluminateContractsAuthAuthenticatable $user * @param array $credentials * @return bool */ public function validateCredentials(Authenticatable $user, array $credentials) { $plain = $credentials['password']; $authPassword = $user->getAuthPassword(); return md5($plain . $authPassword['salt']) == $authPassword['password']; } }3. 将User Providers换成我们⾃⼰的GfzxEloquentUserProvider修改 app/Providers/
namespace AppProviders;
use AppFoundationAuthGfzxEloquentUserProvider; use Auth; use IlluminateSupportFacadesGate; use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider { . . .
/** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies();
Auth::provider('gfzx-eloquent', function ($app, $config) { return new GfzxEloquentUserProvider($this->app['hash'], $config['model']); }); } }4. 修改 config/ 'providers' => [ 'users' => [ 'driver' => 'gfzx-eloquent', 'model' => AppModelsUser::class, ], ],这是就可以⽤过salt+passwrod的⽅式密码认证了⽂章参考到此这篇关于laravel修改⽤户模块的密码验证实现的⽂章就介绍到这了,更多相关laravel修改⽤户模块的密码验证内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
发布者:admin,转转请注明出处:http://www.yc00.com/news/1690464698a353211.html
评论列表(0条)