内容简介:laravel中有一个组件叫auth,auth组件提供了整个框架的认证功能,这里想简单追踪一下它的实现逻辑。生成文件通过
Laravel中的Auth
laravel中有一个组件叫auth,auth组件提供了整个框架的认证功能,这里想简单追踪一下它的实现逻辑。
首先从 php artisan make:auth
开始
# Illuminate\Auth\Console\AuthMakeCommand.php public function handle() { // 创建存放auth前端界面的目录和文件 // 模版存放在Auth\Console的stubs下 $this->createDirectories(); $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 下的控制器
说一说csrf-token
<!-- CSRF Token --> <meta name="csrf-token" content="{{ csrf_token() }}">
function csrf_token() { $session = app('session'); if (isset($session)) { return $session->token(); } throw new RuntimeException('Application session store not set.'); }
LoginController的login方法
public function login(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); }
登录验证方法attemptLogin
通过 Auth::guard()
引导到 Illuminate\Auth\AuthManager
先看 服务提供者 AuthServiceProvider
AuthServiceProvider注册四个服务
protected function registerAuthenticator() { $this->app->singleton('auth', function ($app) { $app['auth.loaded'] = true; // 生成一个AuthManager实例 return new AuthManager($app); }); $this->app->singleton('auth.driver', function ($app) { return $app['auth']->guard(); }); }
protected function registerUserResolver() { $this->app->bind( AuthenticatableContract::class, function ($app) { return call_user_func($app['auth']->userResolver()); } ); }
protected function registerAccessGate() { $this->app->singleton(GateContract::class, function ($app) { return new Gate($app, function () use ($app) { return call_user_func($app['auth']->userResolver()); }); }); }
protected function registerRequestRebindHandler() { $this->app->rebinding('request', function ($app, $request) { $request->setUserResolver(function ($guard = null) use ($app) { return call_user_func($app['auth']->userResolver(), $guard); }); }); }
生成一个AuthManager实例
AuthManager中的trait CreatesUserProviders
这个trait是用来绑定一个用户认证的Eloqument服务提供者
public function __construct($app) { // 绑定application实例 $this->app = $app; // 绑定一个闭包,用于解析用户。 // 通过$guard来确定用户解析用户的方法 $this->userResolver = function ($guard = null) { return $this->guard($guard)->user(); }; } protected function resolve($name) { $config = $this->getConfig($name); // 根据配置调用不同的解析用户的驱动方法 $driverMethod = 'create'.ucfirst($config['driver']).'Driver'; if (method_exists($this, $driverMethod)) { return $this->{$driverMethod}($name, $config); } }
分别定位的两个方法
public function createSessionDriver($name, $config) { // 根据配置文件创建一个相应的provider $provider = $this->createUserProvider($config['provider'] ?? null); $guard = new SessionGuard($name, $provider, $this->app['session.store']); return $guard; } public function createTokenDriver($name, $config) { $guard = new TokenGuard( $this->createUserProvider($config['provider'] ?? null), $this->app['request'], $config['input_key'] ?? 'api_token', $config['storage_key'] ?? 'api_token' ); return $guard; }
于是得到 $this->guard($guard)
的user()方法
先看如何实例一个TokenGuard类
public function __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\TokenGuard public function user() { if (! is_null($this->user)) { return $this->user; } $user = null; // 从request中获取token $token = $this->getTokenForRequest(); if (! empty($token)) { // 通过用户provider中的retrieveByCredentials方法来判断用户是否认证成功 $user = $this->provider->retrieveByCredentials( [$this->storageKey => $token] ); } return $this->user = $user; }
上面都是通用的加载引导调用功能,下面的用户服务提供者则是可以修改自定义的认证的具体功能
认证绑定的用户数据提供者
# Illuminate\Auth\DatabaseUserProvider public function retrieveByCredentials(array $credentials) { if (empty($credentials) || (count($credentials) === 1 && array_key_exists('password', $credentials))) { return; } $query = $this->conn->table($this->table); foreach ($credentials as $key => $value) { if (Str::contains($key, 'password')) { continue; } if (is_array($value) || $value instanceof Arrayable) { $query->whereIn($key, $value); } else { $query->where($key, $value); } } $user = $query->first(); // 返回auth用户数据包 return $this->getGenericUser($user); }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
RGB转16进制工具
RGB HEX 互转工具
HEX HSV 转换工具
HEX HSV 互换工具