当前位置:网站首页>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();
六、附录
边栏推荐
- Memory alignment of structures
- Learn more about redis' eight data types and application scenario analysis
- China solar thermal market trend report, technical dynamic innovation and market forecast
- 23研考生注意啦!备考期间最容易中招的骗局,居然是它们?!
- EPICS記錄參考3 -- 所有記錄都有的字段
- 上新了,华为云开天aPaaS
- A big factory interview must ask: how to solve the problem of TCP reliable transmission? 8 pictures for you to learn in detail
- vulnhub Vegeta: 1
- 推送Markdown格式信息到钉钉机器人
- LeetCode Algorithm 剑指 Offer II 027. 回文链表
猜你喜欢

Spark 离线开发框架设计与实现

推送Markdown格式信息到釘釘機器人

Programmers become gods by digging holes in one year, carrying flags in five years and becoming gods in ten years
![[postgraduate entrance examination English] prepare for 2023, learn list8 words](/img/25/d1f2c2b4c0958d381db87e5ef96df9.jpg)
[postgraduate entrance examination English] prepare for 2023, learn list8 words

JMM 最最最核心的概念:Happens-before 原则

vulnhub DC: 2

Learning bit segment (1)

【Laravel系列7.9】测试

Wechat side: what is consistent hash? In what scenario? What problems have been solved?
![[Wuhan University] information sharing of the first and second postgraduate entrance examinations](/img/ec/884e656a921e20a5679a2960c9ac4d.jpg)
[Wuhan University] information sharing of the first and second postgraduate entrance examinations
随机推荐
EPICS记录参考3 -- 所有记录都有的字段
Solve the problem of port occupation
Vulnhub Vegeta: 1
China smallpox vaccine market trend report, technical innovation and market forecast
Analyze the implementation process of oauth2 distributed authentication and authorization based on the source code
O (n) complexity hand tear sorting interview questions | an article will help you understand counting sorting
Research Report on market evaluation and investment direction of Chinese dermatology drugs (2022 Edition)
The extra points and sharp tools are worthy of the trust | know that Chuangyu won the letter of thanks from the defense side of the attack and defense drill!
China solar window market trend report, technical dynamic innovation and market forecast
LeetCode Algorithm 剑指 Offer 52. 两个链表的第一个公共节点
Common sense of resolution
Dynamic memory management (1)
关于某手滑块的一些更新(6-18,js逆向)
结构体的内存对齐
别再乱用了,这才是 @Validated 和 @Valid 的真正区别!!!
vulnhub DC: 2
2022年高压电工考试模拟100题及在线模拟考试
Stop using it indiscriminately. This is the real difference between @validated and @valid!!!
【ROS玩转Turtlesim小海龟】
Pousser l'information au format markdown vers le robot nail