1. 注册认证中间件, 在文件 app/Http/Kernel.php 内完成:

protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'checkuid' => \App\Http\Middleware\CheckUid::class,
];

2. 认证中间件的源码
文件:vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php 。其中:

use Illuminate\Contracts\Auth\Factory as Auth;
public function __construct(Auth $auth)
{
$this->auth = $auth; //Auth 工厂类,这里注入的是 Illuminate\Auth\AuthManager
} public function handle($request, Closure $next, ...$guards)
{
$this->authenticate($guards);
return $next($request);
} protected function authenticate(array $guards)
{
if (empty($guards)) {//如果没有指定guard 则使用默认
return $this->auth->authenticate(); //通过Illuminate\Auth\AuthManager\__call() 调用 创建guard 实例,并调用guard 实例的 authenticate() 方法进行认证
} foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {//使用指定的guard中第一个能成功认证的
return $this->auth->shouldUse($guard);//将指定guard设置为 本次请求的默认guard。(本次请求后续获取authed user时,都通过这里设置的guard进行)
}
} throw new AuthenticationException('Unauthenticated.', $guards);
}

2.1 $this->auth->authenticate(); //进行身份认证
文件: vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php

public function __call($method, $parameters)
{
return $this->guard()->{$method}(...$parameters);
}

2.2 $this->guard() //获取guard实例
文件: vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php

public function guard($name = null)
{
$name = $name ?: $this->getDefaultDriver(); return isset($this->guards[$name])
? $this->guards[$name] //单例
: $this->guards[$name] = $this->resolve($name); //获取 guard 实例
} public function getDefaultDriver()
{
return $this->app['config']['auth.defaults.guard']; //从配置文件内读取默认guard
} protected function resolve($name)
{
$config = $this->getConfig($name); //获取指定guard配置信息 if (is_null($config)) {
throw new InvalidArgumentException("Auth guard [{$name}] is not defined.");
} if (isset($this->customCreators[$config['driver']])) {//如果设置了自定义工厂,则使用之
return $this->callCustomCreator($name, $config);
} //类似 createSessionDriver, createTokenDriver 等格式
$driverMethod = 'create'.ucfirst($config['driver']).'Driver'; if (method_exists($this, $driverMethod)) {
return $this->{$driverMethod}($name, $config);
} throw new InvalidArgumentException("Auth guard driver [{$name}] is not defined.");
} public function createSessionDriver($name, $config)
{
$provider = $this->createUserProvider($config['provider']); $guard = new SessionGuard($name, $provider, $this->app['session.store']); //When using the remember me functionality of the authentication services we
//will need to be set the encryption instance of the guard, which allows
//secure, encrypted cookie values to get generated for those cookies.
if (method_exists($guard, 'setCookieJar')) {
$guard->setCookieJar($this->app['cookie']);
} if (method_exists($guard, 'setDispatcher')) {
$guard->setDispatcher($this->app['events']);
} if (method_exists($guard, 'setRequest')) {
$guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
} return $guard;
}

2.3 $this->guard()->authenticate() //使用获取的 guard 实例进行身份认证
文件: vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php
类中 use 了 GuardHelpers trait
文件:vendor/laravel/framework/src/Illuminate/Auth/GuardHelpers.php

public function authenticate()
{
if (! is_null($user = $this->user())) {
return $user;
} throw new AuthenticationException;
}

文件: vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php //此方法是真正进行身份认证的地方!!!!

public function user()
{
if ($this->loggedOut) {
return;
} // If we've already retrieved the user for the current request we can just
// return it back immediately. We do not want to fetch the user data on
// every call to this method because that would be tremendously slow.
if (! is_null($this->user)) {
return $this->user;
} $id = $this->session->get($this->getName()); //从session中获取用户ID。已登录用户的用户ID会被存储在Session内。 // First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null; if (! is_null($id)) {
if ($user = $this->provider->retrieveById($id)) { //通过Illuminate\Auth\EloquentUserProvider 的retrieveById() 方法,获取用户信息,并返回User Model
$this->fireAuthenticatedEvent($user);
}
} // If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();//获取认证cookie(登录时选中记住我,服务端会向浏览器设置一个认证cookie,其中包括 remember_token,下次可以直接使用这个认证cookie进行登录) if (is_null($user) && ! is_null($recaller)) {
$user = $this->getUserByRecaller($recaller); //使用 remember_token 从数据库中获取用户信息 (最终是委托 Illuminate\Auth\EloquentUserProvider::retrieveByToken() 方法来取数据) if ($user) {
$this->updateSession($user->getAuthIdentifier()); //将用户ID保存到Session
$this->fireLoginEvent($user, true);
}
} return $this->user = $user;
}

原文地址:http://www.cnblogs.com/tao100/p/6073542.html

最新文章

  1. PL/SQL连接错误:ora-12705:cannot access NLS data files or invalid environment specified
  2. C#进阶系列——MEF实现设计上的“松耦合”(二)
  3. C和指针 第十一章 习题
  4. STM3210x建工程库函数版本
  5. 【CodeVS 1218】【NOIP 2012】疫情控制
  6. MFC+Android模拟器 实现 自动玩“天天爱消除”
  7. css样式重置方案 -解决浏览器差异
  8. sqlserver2008安装教程
  9. mysql_fetch_row,mysql_fetch_array,mysql_fetch_object,mysql_fetch_assoc区别
  10. C#中默认的修饰符
  11. super.getClass()方法
  12. 方法:查询MongoDB数据库中最新一条数据(JAVA)
  13. LeetCode 341. Flatten Nested List Iterator
  14. MT9M021/MT9M031总结
  15. linux 线程回顾
  16. [UWP]如何使用Fluent Design System (下)
  17. assert断言检测
  18. Kaldi阅读并更改代码
  19. 转:zTree高级入门:如何通过扩展节点的属性来达到是否显示节点的删除编辑等图标(按钮)
  20. 作业:WordCount--实现字符数,单词数,行数的统计

热门文章

  1. Android中自动跳转
  2. 高级C/C++编译技术之读书笔记(二)之库的概念
  3. python3 selenium 安装以及验证
  4. wifi文件传输
  5. AtCoder Grand Contest 017 迟到记
  6. 恢复所有情况的ip地址
  7. Java问题:中间件是什么
  8. 遍历listmap 遍历map
  9. C语言通过地址传递参数
  10. PHP中的精确计算bcadd,bcsub,bcmul,bcdiv