Laravel认证原理以及完全自定义认证详解
前言
Laravel默认的auth功能已经是很全面了,但是我们也经常会碰到一些需要自定义的一些情况,比如验证的字段和默认的不匹配,比如需要能够同时满足username和email认证等等。如何创建一个完全自定义的认证呢?相比一个教程,我更倾向于介绍一下工作原理,这样在自己修改或自定义的过程中更得心应手。
Authenticatable接口
Illuminate\Contracts\Auth\Authenticatable
Authenticatable定义了一个可以被用来认证的模型或类需要实现的接口,也就是说,如果需要用一个自定义的类来做认证,需要实现这个接口定义的方法。
//获取唯一标识的,可以用来认证的字段名,比如id,uuid publicfunctiongetAuthIdentifierName(); //获取该标示符对应的值 publicfunctiongetAuthIdentifier(); //获取认证的密码 publicfunctiongetAuthPassword(); //获取remembertoken publicfunctiongetRememberToken(); //设置remembertoken publicfunctionsetRememberToken($value); //获取remembertoken对应的字段名,比如默认的'remember_token' publicfunctiongetRememberTokenName();
比如你的认证模型需要用'token'而不是'password'来作为密码验证,这个时候就可以修改getAuthPassword()方法的返回值为'token';
Authenticatabletrait
Illuminate\Auth\Authenticatable
Laravel中定义的Authenticatabletrait,也是Laravelauth默认的User模型使用的trait,这个trait定义了User模型默认认证标示符为'id',密码字段为'password',remembertoken对应的字段为remember_token等等。
通过重写User模型的这些方法可以修改一些设置。
Guard接口
Illuminate\Contracts\Auth\Guard
Guard接口定义了某个实现了Authenticatable(可认证的)模型或类的认证方法以及一些常用的接口。
//判断当前用户是否登录 publicfunctioncheck(); //判断当前用户是否是游客(未登录) publicfunctionguest(); //获取当前认证的用户 publicfunctionuser(); //获取当前认证用户的id,严格来说不一定是id,应该是上个模型中定义的唯一的字段名 publicfunctionid(); //根据提供的消息认证用户 publicfunctionvalidate(array$credentials=[]); //设置当前用户 publicfunctionsetUser(Authenticatable$user);
StatefulGuard接口
Illuminate\Contracts\Auth\StatefulGuard
StatefulGuard接口继承自Guard接口,除了Guard里面定义的一些基本接口外,还增加了更进一步、有状态的Guard.
新添加的接口有这些:
//尝试根据提供的凭证验证用户是否合法 publicfunctionattempt(array$credentials=[],$remember=false); //一次性登录,不记录sessionorcookie publicfunctiononce(array$credentials=[]); //登录用户,通常在验证成功后记录session和cookie publicfunctionlogin(Authenticatable$user,$remember=false); //使用用户id登录 publicfunctionloginUsingId($id,$remember=false); //使用用户ID登录,但是不记录session和cookie publicfunctiononceUsingId($id); //通过cookie中的remembertoken自动登录 publicfunctionviaRemember(); //登出 publicfunctionlogout();
Laravel中默认提供了3中guard:RequestGuard,TokenGuard,SessionGuard.
RequestGuard
Illuminate\Auth\RequestGuard
RequestGuard是一个非常简单的guard.RequestGuard是通过传入一个闭包来认证的。可以通过调用Auth::viaRequest添加一个自定义的RequestGuard.
SessionGuard
Illuminate\Auth\SessionGuard
SessionGuard是Laravelweb认证默认的guard.
TokenGuard
Illuminate\Auth\TokenGuard
TokenGuard适用于无状态api认证,通过token认证.
UserProvider接口
Illuminate\Contracts\Auth\UserProvider
UserProvider接口定义了获取认证模型的方法,比如根据id获取模型,根据email获取模型等等.
//通过唯一标示符获取认证模型 publicfunctionretrieveById($identifier); //通过唯一标示符和remembertoken获取模型 publicfunctionretrieveByToken($identifier,$token); //通过给定的认证模型更新remembertoken publicfunctionupdateRememberToken(Authenticatable$user,$token); //通过给定的凭证获取用户,比如email或用户名等等 publicfunctionretrieveByCredentials(array$credentials); //认证给定的用户和给定的凭证是否符合 publicfunctionvalidateCredentials(Authenticatable$user,array$credentials);
Laravel中默认有两个userprovider:DatabaseUserProvider&EloquentUserProvider.
DatabaseUserProvider
Illuminate\Auth\DatabaseUserProvider
直接通过数据库表来获取认证模型.
EloquentUserProvider
Illuminate\Auth\EloquentUserProvider
通过eloquent模型来获取认证模型
AuthManager
Illuminate\Auth\AuthManager
Guard用来认证一个用户是否认证成功,UserProvider用来提供认证模型的来源,而根据项目的config管理guard以及自定义guard等等功能,则是通过AuthManager来实现。
AuthManager应该是有点像策略模式里面的Context类以及工厂方法里面的工厂,一方面管理Guard,另外一方面通过__call魔术方法调用具体的策略(Guard)方法。
Authfacade对应的实现类就是AuthManager,AuthManager在容器中注册为单例,用来管理所有的guard、userprovider以及guard的代理工作。
自定义认证
根据上面的知识,可以知道要自定义一个认证很简单。
- 创建认证模型
创建一个自定义的认证模型,实现Authenticatable接口;
- 创建自定义的UserProvider
创建一个自定义的UserProvider,实现UserProvider接口,可以返回上面自定义的认证模型;
- 创建自定义的Guard
创建一个自定义的Guard,实现Guard或StatefulGuard接口
- 添加guardcreator和userprovidercreator到AuthManager中
在AppServiceProvider的boot方法添加如下代码:
Auth::extend('myguard',function(){ ... returnnewMyGuard();//返回自定义guard实例 ... }); Auth::provider('myuserprovider',function(){ returnnewMyUserProvider();//返回自定义的userprovider });
在config\auth.php的guards数组中添加自定义guard,一个自定义guard包括两部分:driver和provider.
'oustn'=>[ 'driver'=>'myguard', 'provider'=>'myusers', ],
在config\auth.php的providers数组中添加自定义userprovider.
'myusers'=>[ 'driver'=>'myuserprovider'//里面具体的字段可以根据你创建userprovider需要的信息自由添加,可以通过Auth::createUserProvider('myuserprovider')创建 ],
设置config\auth.php的defaults.guard为oustn.
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。