Laravel Auth原理的示例分析
作者
这篇文章给大家分享的是有关Laravel Auth原理的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
由于公司最近使用Laravel-admin做后台,接触了下Laravel框架,不得不说,Laravel社区的力量以及生态确实挺强大。
但是公司内部业务都处于Java端,后台全部都是调JavaApi,因此使用Laravel的特性就得大打折扣了,首先Eloquent模型完全不能用,我这边把业务分开来,只存了3张表,这是Laravel-admin自带的表。
Laravel-admin带了9张表,由于用户登录业务全保存在Api端,自带的表功能被我割舍了。因此需要自己实现Api登录的逻辑,而又必须走Laravel Auth认证。
原理解读
//使用下面这个命令Laravel会自动为我们生成Auth路由和认证模块。跟着代码往下解读。 phpartisanmake:auth //Http/Controllers/Auth/LoginController 使用了 AuthenticatesUsers
其中 下面这三个方法诠释了登录逻辑的全部。
publicfunctionlogin(Request$request) { $this->validateLogin($request); if($this->hasTooManyLoginAttempts($request)){ $this->fireLockoutEvent($request); return$this->sendLockoutResponse($request); } //这里尝试登录系统, if($this->attemptLogin($request)){ return$this->sendLoginResponse($request); } $this->incrementLoginAttempts($request); return$this->sendFailedLoginResponse($request); } protectedfunctionattemptLogin(Request$request) { return$this->guard()->attempt( $this->credentials($request),$request->has('remember') ); } protectedfunctionguard() { returnAuth::guard(); }
控制器会去寻找Auth::guard(), 那这个Auth::guard()是个什么东西呢,
首先 Auth 是系统的单例,原型在
Illuminate\Auth\AuthManager;
顾名思义,是一个Auth管理模块,实现了认证工厂模式接口guards(),
publicfunction__construct($app) { $this->app=$app; $this->userResolver=function($guard=null){ return$this->guard($guard)->user(); }; } //Auth::guard();就是调用了这个方法。 publicfunctionguard($name=null) { //首先查找$name,没有就使用默认的驱动, $name=$name?:$this->getDefaultDriver(); //意思就是要实例化出这个驱动并且返回, returnisset($this->guards[$name]) ?$this->guards[$name] :$this->guards[$name]=$this->resolve($name); } //默认的驱动是从配置文件里面读取的,/config/auth.php default配置项 publicfunctiongetDefaultDriver() { return$this->app['config']['auth.defaults.guard']; } //这里是构造Auth-guard驱动 protectedfunctionresolve($name) { $config=$this->getConfig($name); if(is_null($config)){ thrownewInvalidArgumentException("xxx"); } //这里是如果你自己实现的驱动就返回 if(isset($this->customCreators[$config['driver']])){ return$this->callCustomCreator($name,$config); } //这里是系统默认两个类分别是 //session和token这里主要讲sessionGuard. $driverMethod='create'.ucfirst($config['driver']).'Driver'; if(method_exists($this,$driverMethod)){ return$this->{$driverMethod}($name,$config); } thrownewInvalidArgumentException("xxx"); }
接下来看看配置文件 auth.php
//Auth::guard(),不传参数,就调用默认的default.guard, 'defaults'=>[ 'guard'=>'web', 'passwords'=>'users', ], //系统的guard.默认支持"database","eloquent",意思就是说你的provider必须是这两个实例中的一个, 'guards'=>[ 'web'=>[ 'driver'=>'session', 'provider'=>'users', ], 'api'=>[ 'driver'=>'token', 'provider'=>'users', ], ], //这个就是上面的provider了,你使用哪一个provider作为你的Auth::guard()返回的 //模型 'providers'=>[ 'users'=>[ 'driver'=>'eloquent', 'model'=>App\User::class, ], //'users'=>[ //'driver'=>'database', //'table'=>'users', //], ],
也就是说终归到底,Auth::guard(), 在默认配置里面是给我反回了一个sessionGuard .
主要看下面4个方法
namespaceIlluminate\Auth; classSessionGuard{ publicfunctionattempt(array$credentials=[],$remember=false) { //这里触发 试图登录事件,此时还没有登录 $this->fireAttemptEvent($credentials,$remember); $this->lastAttempted= $user=$this->provider->retrieveByCredentials($credentials); //这里会调用hasValidCredentials,其实就是验证用户名和密码的一个过程 if($this->hasValidCredentials($user,$credentials)){ //如果验证通过了,就调用login方法. $this->login($user,$remember); returntrue; } //否则就触发登录失败事件,返回假 $this->fireFailedEvent($user,$credentials); returnfalse; } //这里是登录用户的操作,就是说调用这个方法已经是合法用户了,必须是一个 //AuthenticatableContract的实例. publicfunctionlogin(AuthenticatableContract$user, $remember=false) { //直接更新session,这里就是把session存起来,session的键在该方法的 //getName()里边, $this->updateSession($user->getAuthIdentifier()); if($remember){ $this->ensureRememberTokenIsSet($user); $this->queueRecallerCookie($user); } //触发登录事件,已经登录了这个时候, $this->fireLoginEvent($user,$remember); //将user对象保存到sessionGuard,后续的类访问Auth::user();直接拿到 $this->setUser($user); } //这里就是经常使用到的Auth::user()了,具体如何返回看AuthManager里面的 //__call publicfunctionuser() { if($this->loggedOut){ return; } if(!is_null($this->user)){ return$this->user; } //这里读取session拿到user的id , $id=$this->session->get($this->getName()); $user=null; //如果拿到了id,查找到该user if(!is_null($id)){ if($user=$this->provider->retrieveById($id)){ $this->fireAuthenticatedEvent($user); } } $recaller=$this->recaller(); if(is_null($user)&&!is_null($recaller)){ $user=$this->userFromRecaller($recaller); if($user){ $this->updateSession($user->getAuthIdentifier()); $this->fireLoginEvent($user,true); } } return$this->user=$user; } //这里就直接返回用户id了, publicfunctionid() { if($this->loggedOut){ return; } return$this->user() ?$this->user()->getAuthIdentifier() :$this->session->get($this->getName()); } }
大体上用户登录的流程就完了,简单过程就是
//伪代码 $credentials=$request()->only(['username','password']); if(Auth::guard("session")->attempt($credentials)){ //登录成功 }else{ //登录失败 }
实现用户登录之后才能访问的控制器/方法
Route::get("/home")->middleware("auth"); //authMiddleware是在app/Http/Kernel中注册的, //类名是\Illuminate\Auth\Middleware\Authenticate::class //解析过程实质上是这个方法: publicfunctionhandle($request,Closure$next,...$guards) { $this->authenticate($guards); return$next($request); } protectedfunctionauthenticate(array$guards) { //默认情况下会去Auth中寻找authenticate这个方法 if(empty($guards)){ return$this->auth->authenticate(); } //如果middleware中传了参数,会遍历一遍,不通过就抛出异常 foreach($guardsas$guard){ if($this->auth->guard($guard)->check()){ return$this->auth->shouldUse($guard); } } thrownewAuthenticationException('Unauthenticated.',$guards); } //sessionGuard中的authenticate其实也就是调用了一遍user方法。 publicfunctionauthenticate() { if(!is_null($user=$this->user())){ return$user; } thrownewAuthenticationException; }
感谢各位的阅读!关于“Laravel Auth原理的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
目录
推荐阅读
0 条评论
本站已关闭游客评论,请登录或者注册后再评论吧~