一聚教程网:一个值得你收藏的教程网站

热门教程

laravel修改用户模块的密码验证实现

时间:2026-05-28 09:30:02 编辑:袖梨 来源:一聚教程网

本文主要介绍了laravel修改用户模块的密码验证实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

从配置文件入手

用户认证相关的配置都保存在config/auth.php文件中,先来看看配置文件的内容:

<?phpreturn [/*|--------------------------------------------------------------------------| 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方法:

//IlluminateAuthEloquentUserProviderpublic 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. * * @parammixed$user * @paramarray$credentials * @return bool */protected function hasValidCredentials($user, $credentials){return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);}

进一步查看EloquentUserProvider中的validateCredentials方法

//IlluminateAuthEloquentUserProviderpublic 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方法,正确获取密码字段:

// AppAdminpublic function getAuthPassword(){return $this->login_pass;}

不出意外的话,这个时候就能使用admins表进行登录了。

Larval 5.4的默认Auth登陆传入邮件和用户密码到attempt 方法来认证,通过email 的值获取,如果用户被找到,经哈希运算后存储在数据中的password将会和传递过来的经哈希运算处理的passwrod值进行比较。如果两个经哈希运算的密码相匹配那么将会为这个用户开启一个认证Session。

参考上面的分析,我们就需要对EloquentUserProvider中的validateCredentials方法进行重写,步骤如下

1. 修改 AppModelsUser.php 添加如下代码

public function getAuthPassword(){return ['password' => $this->attributes['password'], 'salt' => $this->attributes['salt']];}

2. 建立一个自己的UserProvider.php 的实现

<?php namespace AppFoundationAuth;use IlluminateAuthEloquentUserProvider;use IlluminateContractsAuthAuthenticatable;use IlluminateSupportStr;/** * 重写用户密码校验逻辑 * Class GfzxEloquentUserProvider * @package AppFoundationAuth */class GfzxEloquentUserProvider extends EloquentUserProvider{/** * Validate a user against the given credentials. * * @paramIlluminateContractsAuthAuthenticatable $user * @paramarray $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/AuthServiceProvider.php

<?phpnamespace 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/auth.php

 'providers' => ['users' => ['driver' => 'gfzx-eloquent','model' => AppModelsUser::class,],],

这是就可以用过salt+passwrod的方式密码认证了

文章参考

laravel 修改用户模块密码验证

Laravel 中自定义用户登录的数据表

到此这篇关于laravel修改用户模块的密码验证实现的文章就介绍到这了,更多相关laravel修改用户模块的密码验证内容请搜索一聚教程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持一聚教程网!

热门栏目