当前位置:网站首页>Laravel 认证模块 auth
Laravel 认证模块 auth
2022-06-24 19:41:00 【王道长的编程之路】
一、配置
config/auth.php
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',//指向llluminate/Auth/SessionGuard.php
'provider' => 'users',
],
'api' => [
'driver' => 'token', //指向llluminate/Auth/TokenGuard.php
'provider' => 'wx_user',
'hash' => false,//TokenGuard.php文件类属性
'input' => 'token', //TokenGuard.php文件类属性
'storage_key' => 'token', //TokenGuard.php文件类属性
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'wx_user' => [
'driver' => 'eloquent',
'model' =>App\Model\UserModel::class,
]
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
二、基础使用
Auth::check() //判断用户是否登陆,false则重定向/login,为什么用Redirect::guest()而不用Redirect::to()?因为guest() 重定向时会将当前url保存到session中,登陆后用Redirect::intended()方法跳转之前页面。
Auth::attempt(array('email' => $email, 'password' => $password)) //attempt 接收数组作为参数1,该参的值将用于寻找数据库中的用户数据。如用 email 值在数据库中查找,如找到则将 password 值哈希加密并与数据库中密码匹配,如果匹配到,则创建认证通过的会话给用户。当用户身份认证成功 attempt 方法会返回 true,反之则返回 false。
//Auth只帮助实现验证逻辑,如果成功会写入session,下次Auth::check()的时就通过了。
//Redirect::intended(‘/’)跳转到之前页面,如Redirect::guest()方法,那intended会跳转到那时的url,而它的参数只是个默认值,再没有记录历史url的时候会跳转到’/’。
//Auth还有些其他方法,如 Auth::basic() 可实现http basic认证。
三、自定义加密验证
3.1 寻找auth模块
# config/app.php
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
调用Auth其实是调用 Illuminate\Support\Facades\Auth::class ,打开文件
class Auth extends Facade{
protected static function getFacadeAccessor(){
return 'auth';
}
}
Auth是通过Facade动态绑定的,绑定到 vendor/laravel/framework/src/Illuminate/AuthServiceProvider中
class AuthServiceProvider extends ServiceProvider{
protected function registerAuthenticator(){
$this->app->singleton('auth', function ($app) {
$app['auth.loaded'] = true;
return new AuthManager($app);
});
$this->app->singleton('auth.driver', function ($app) {
return $app['auth']->guard();
});
}
}
默认Auth绑定了AuthManager,打开AuthManager文件
<?php
namespace Illuminate\Auth;
use Closure;
use InvalidArgumentException;
use Illuminate\Contracts\Auth\Factory as FactoryContract;
class AuthManager implements FactoryContract{
use CreatesUserProviders;
protected $app;
protected $guards = [];
public function guard($name = null){
$name = $name ?: $this->getDefaultDriver();
return $this->guards[$name]??$this->guards[$name] = $this->resolve($name);
}
public function getDefaultDriver(){
return $this->app['config']['auth.defaults.guard'];
}
public function __call($method, $parameters){
return $this->guard()->{
$method}(...$parameters);
}
}
没找到attempt方法,但有__call魔术方法,直接用 dd(get_class($this->guard())); 真正的attempt被谁调用呢?打印SessionGuard,打开Illuminate\Auth\SessionGuard,终于发现attempt实现
class SessionGuard implements StatefulGuard, SupportsBasicAuth
{
use GuardHelpers, Macroable;
public function attempt(array $credentials = [], $remember = false){
$this->fireAttemptEvent($credentials, $remember);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
if ($this->hasValidCredentials($user, $credentials)) {
$this->login($user, $remember);
return true;
}
$this->fireFailedEvent($user, $credentials);
return false;
}
这是attempt实现,通过 $this->provider->retrieveByCredentials($credentials)获取用户信息,并验证,如果成功则登录,并返回true,所以我们真正做的密码验证肯定在retrieveByCredentials这个方法里面 Laravel 默认提供了 UserProvider 为 EloquentUserProvider 打开改方法
class EloquentUserProvider implements UserProvider{
protected $hasher;
protected $model;
public function __construct(HasherContract $hasher, $model){
$this->model = $model;
$this->hasher = $hasher;
}
public function validateCredentials(UserContract $user, array $credentials){
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
public function setHasher(HasherContract $hasher){
$this->hasher = $hasher;
return $this;
}
}
所以这里的hasher就是系统默认的BcryptHasher了,修改他并注入自己的haser。ok,开始搞它
3.2 编写自己的密码规则hasher
<?php
namespace App\Helpers\Hasher;
use Illuminate\Contracts\Hashing\Hasher;
class MD5Hasher implements Hasher{
public function check($value, $hashedValue, array $options = []){
return $this->make($value) === $hashedValue;
}
public function needsRehash($hashedValue, array $options = []){
return false;
}
public function make($value, array $options = []){
$value = env('SALT', '').$value;
return md5($value); //这里写你自定义的加密方法
}
}
3.3 用自己的Hasher替换默认的Hasher
创建MD5HashServiceProvider
php artisan make:provider MD5HashServiceProvider
添加如下方法
<?php
namespace App\Providers;
use App\Helpers\Hasher\MD5Hasher;
use Illuminate\Support\ServiceProvider;
class MD5HashServiceProvider extends ServiceProvider{
public function boot(){
$this->app->singleton('hash', function () {
return new MD5Hasher;
});
}
public function register(){
}
public function provides(){
return ['hash'];
}
}
然后在config/app.php的providers中,将 Illuminate\Hashing\HashServiceProvider::class, 替换为 \App\Providers\MD5HashServiceProvider::class,
OK,大功告成
四、自定义auth 验证
4.1 修改 user model
# 新增,获取需验证的字段
public function getAuthPassword (){
return [
'password'=> $this->attributes['password'],
'salt'=> $this->attributes['code']
];
}
4.2 新增 provider
php artisan make:provider UserServiceProvider
# 重写EloquentUserProvider类的validateCredentials方法
class MyUserProvider extends EloquentUserProvider{
public function __construct (HasherContract $hasher, $model){
$this->model = $model;
$this->hasher = $hasher;
}
public function register(){
}
public function boot(){
}
// 认证给定的用户和给定的凭证是否符合
public function validateCredentials (Authenticatable $user, array $credentials){
$plain = $credentials['password'];
$secret = $user->getAuthPassword();
if(password_verify($plain, $secret)){
return true;
} elseif($this->think_ucenter_md5($plain) === $secret){
$user->password = password_hash($plain, PASSWORD_DEFAULT);
$user->save();
return true;
}
}
public function think_ucenter_md5 ($str){
return md5(sha1($str) . 'VvKl0QZBE7nao5xtXqGkWrMPchRbHdwmLF361izT');
}
}
4.3 在 AppServiceProvider 的 boot 注册
Auth::provider('myuserprovider', function(){
return new MyUserProvider(); // 返回自定义的 user provider
});
4.4 修改 config/auth.php
在 config\auth.php 的 guards 数组中添加自定义 guard,一个自定义 guard 包括两部分: driver 和 provider.
'oustn' => [
'driver' => 'myguard',
'provider' => 'myusers',
],
...
//在providers 数组中添加自定义 user provider
'myusers' => [
'driver' => 'myuserprovider' //具体字段根据创建 user provider 的信息添加,通过 Auth::createUserProvider('myuserprovider')创建
],
五、auth常用函数
<?php
Auth::guard("api")->user();// 获取当前认证的用户
Auth::guard("api")->check();// 判断当前用户是否登录
Auth::guard("api")->guest();// 判断当前用户是否是游客(未登录)
Auth::guard("api")->validate();// 根据提供的消息认证用户
Auth::guard("api")->setUser();// 设置当前用户
Auth::guard("api")->attempt();// 根据提供的凭证验证用户是否合法
Auth::guard("api")->id();
六、附录
边栏推荐
- Pousser l'information au format markdown vers le robot nail
- How to submit the shopee opening and settlement flow?
- China Sky Lantern market trend report, technical dynamic innovation and market forecast
- 倍加福(P+F)R2000修改雷达IP
- win10或win11打印机无法打印
- 非单文件组件
- A big factory interview must ask: how to solve the problem of TCP reliable transmission? 8 pictures for you to learn in detail
- Spark 离线开发框架设计与实现
- Canvas to add watermark to pictures
- 加分利器 不负所托 | 知道创宇获攻防演练防守方感谢信!
猜你喜欢

Analyze the implementation process of oauth2 distributed authentication and authorization based on the source code

结合源码剖析Oauth2分布式认证与授权的实现流程

Solve the problem of non secure websites requesting localhost to report CORS after chrome94

Wechat side: what is consistent hash? In what scenario? What problems have been solved?

【Mongodb】READ_ME_TO_RECOVER_YOUR_DATA,数据库被恶意删除

Introduction to machine learning compilation course learning notes lesson 1 overview of machine learning compilation

Canvas to add watermark to pictures

Spark 离线开发框架设计与实现
![[QT] QT event handling](/img/48/14a5491307fee1c99434d6cb308337.jpg)
[QT] QT event handling

Combine pod identity in aks and secret in CSI driver mount key vault
随机推荐
Second IPO of Huafang group: grown up in Zanthoxylum bungeanum, trapped in Zanthoxylum bungeanum
「ARM 架构」是一种怎样的处理器架构?
MySQL夺命10问,你能坚持到第几问?
shopee开店入驻流水如何提交?
Research Report on market supply and demand and strategy of ceiling power supply device industry in China
docker安装redis-简单而无坑
动态菜单,自动对齐
Dynamic menu, auto align
Sword finger offer 42 Maximum sum of successive subarrays
ACL (access control list) basic chapter - Super interesting learning network
See how sparksql supports enterprise level data warehouse
剑指 Offer 13. 机器人的运动范围
Based on the codeless platform, users deeply participated in the construction, and digital data + Nanjing Fiberglass Institute jointly built a national smart laboratory solution
EPICS记录参考2--EPICS过程数据库概念
环境配置 | VS2017配置OpenMesh源码和环境
Learn more about the practical application of sentinel
Solve the problem of port occupation
【文本数据挖掘】中文命名实体识别:HMM模型+BiLSTM_CRF模型(Pytorch)【调研与实验分析】
2022-06-10 work record --js- obtain the date n days after a certain date
推送Markdown格式信息到钉钉机器人