Laravel中的Auth中有一个名为auth的组件。auth组件提供了整个框架的认证功能。这里我想简单的跟踪一下它的实现逻辑。首先开始phpartisanmake:auth#Illuminate\Auth\Console\AuthMakeCommand.phppublicfunctionhandle(){//创建存放auth前端接口的目录和文件//模板存放在Auth\Console的存根下$这个->创建目录();$this->exportViews();if(!$this->option('views')){//生成HomeController控制器文件file_put_contents(app_path('Http/Controllers/HomeController.php'),$this->compileControllerStub());//生成auth相关路由file_put_contents(base_path('routes/web.php'),file_get_contents(__DIR__.'/stubs/make/routes.stub'),FILE_APPEND);}}生成文件resources/views/auth,resources/layouts路由文件web.php,Http/Controllers/Auth下的controller讲csrf-tokenfunctioncsrf_token(){$session=app('session');如果(isset($session)){返回$session->token();}抛出新的RuntimeException('应用程序会话存储未设置。');}LoginController的登录方法publicfunctionlogin(Request$request){//检查请求体$this->validateLogin($request);//判断请求是否失败次数过多if($this->hasTooManyLoginAttempts($request)){$this->fireLockoutEvent($request);返回$this->sendLockoutResponse($request);}//判断验证是否通过if($this->attemptLogin($request)){return$this->sendLoginResponse($request);}//记录请求失败的次数$this->incrementLoginAttempts($request);返回$this->sendFailedLoginResponse($request);}登录验证方法attemptLogin通过Auth::guard()指导Illuminate\Auth\AuthManagerFirstLookServiceProviderAuthServiceProviderAuthServiceProvider注册四个服务protectedfunctionregisterAuthenticator(){$this->app->singleton('auth',function($app){$app['auth.loaded']=true;//生成一个AuthManager实例returnnewAuthManager($app);});$this->app->singleton('auth.driver',function($app){return$app['auth']->guard();});}protectedfunctionregisterUserResolver(){$this->app->bind(AuthenticatableContract::class,function($app){returncall_user_func($app['auth']->userResolver());});}protectedfunctionregisterAccessGate(){$this->app->singleton(GateContract::class,function($app){returnnewGate($app,function()use($app){returncall_user_func($app['auth']->userResolver());});});}protectedfunctionregisterRequestRebindHandler(){$this->app->rebinding('request',function($app,$request){$request->setUserResolver(function($guard=null)use($app){返回call_user_func($app['auth']->userResolver(),$guard);});});}生成一个AuthManager实例。AuthManager中的TraitCreatesUserProviders用于绑定一个Eloqument服务提供者用于用户认证publicfunction__construct($app){//绑定应用实例$this->app=$app;//为解析用户绑定一个闭包//使用$guard判断用户解析的方法$this->userResolver=function($guard=null){return$this->guard($guard)->user();};}protectedfunctionresolve($name){$config=$this->getConfig($name);//根据配置调用不同的驱动方法解析用户$driverMethod='create'.ucfirst($config['driver']).'Driver';如果(method_exists($this,$driverMethod)){return$this->{$driverMethod}($name,$config);}}两个方法分别位于publicfunctioncreateSessionDriver($name,$config){//根据配置文件创建对应的provider$provider=$this->createUserProvider($config['provider']??null);$guard=newSessionGuard($name,$provider,$this->app['session.store']);返回$守卫;}publicfunctioncreateTokenDriver($name,$config){$guard=newTokenGuard($this->createUserProvider($config['provi德']??null),$this->app['request'],$config['input_key']??'api_token',$config['storage_key']??'api_token');返回$守卫;}于是得到了$this->guard($guard)的user()方法先来看看如何实例化一个TokenGuard类publicfunction__construct(UserProvider$provider,Request$request,$inputKey='api_token',$storageKey='api_token'){$this->request=$request;$this->provider=$provider;$this->inputKey=$inputKey;$this->storageKey=$storageKey;}#Illuminate\Auth\TokenGuardpublicfunctionuser(){if(!is_null($this->user)){return$this->user;}$用户=空;//从请求中获取令牌$token=$this->getTokenForRequest();if(!empty($token)){//在userprovider中使用retrieveByCredentials方法判断用户是否认证成功$user=$this->provider->retrieveByCredentials([$this->storageKey=>$token]);}返回$this->user=$user;}以上都是通用的加载引导调用函数,下面的用户服务提供者可以修改自定义认证具体功能认证绑定用户数据提供者#Illuminate\Auth\DatabaseUserProviderpublicfunctionretrieveByCredentials(array$credentials){if(empty($credentials)||(count($credentials)===1&&array_key_exists('password',$credentials))){返回;$query=$this->conn->table($this->table);foreach($credentialsas$key=>$value){if(Str::contains($key,'password')){继续;}if(is_array($value)||$valueinstanceofArrayable){$query->whereIn($key,$value);}else{$query->where($key,$value);}}$user=$query->first();//返回auth用户数据包return$this->getGenericUser($user);}