每个控制器都使用 trait 来引入它们需要的方法 */
用于处理用户登录认证
用于处理新用户注册
包含重置密码逻辑
用于处理重置密码邮件链接
 
认证需要的视图
包含了应用的基础布局文件
 
 
Auth::routes();
 
static::$app->make('router')->auth();
 
 
 
 
 
 
 
注册
 
 
 
public function showRegistrationForm()
{
return view('auth.register');
}
return view('auth.register');
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
 
1. $this->validator($request->all())->validate();
 
 
$this->validator() protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
如果我们的用户注册需要的表单与这几个字段不一致(例如需要添加一个手机号),就在这里修改
event(new Registered($user = $this->create($request->all())));
 
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
利用 request 参数创建一个新用户,然后返回用户实例。接着触发用户注册事件。
3. $this->guard()->login($user);
 
$this->guard()
 
 
'defaults' => [
'guard' => 'web', # 'passwords' => 'users',
],
 
'guards' => [
'web' => [
'driver' => 'session', Illuminate\Auth\SessionGuard::class
'provider' => 'users',
],
 
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
 
'providers' => [
'users' => [
'driver' => 'eloquent', Illuminate\Auth\EloquentUserProvider::class
'model' => App\User::class, #App\User::class
],
 
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
 
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
 
App\User
 
方法:
 
文件 vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php 内:
 
public function login(AuthenticatableContract $user, $remember = false)
{
$this->updateSession($user->getAuthIdentifier());
 
// If the user should be permanently "remembered" by the application we will
// queue a permanent cookie that contains the encrypted copy of the user
// identifier. We will then decrypt this later to retrieve the users.
if ($remember) {
$this->createRememberTokenIfDoesntExist($user); //如果用户选中了“记住我”,则生产remember_token
 
$this->queueRecallerCookie($user);
}
 
// If we have an event dispatcher instance set we will fire an event so that
// any listeners will hook into the authentication events and run actions
// based on the login and logout events fired from the guard instances.
$this->fireLoginEvent($user, $remember);
 
$this->setUser($user);
}
其中 $user->getAuthIdentifier() 用来获取用户唯一标识( Illuminate\Auth\Authenticatable::getAuthIdentifier)
 
其中 $this->updateSession(); 实现如下:
protected function updateSession($id)
{
$this->session->set($this->getName(), $id); //将用户唯一标识写入Session,记录登录状态
$this->session->migrate(true); //更新SessionID同时保留Session所有属性
}
 
4. return $this->registered($request, $user)
?: redirect($this->redirectPath());
 
public function redirectPath()
{
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
 
 
DRY 原则
登录(认证)
 
认证
$this->post('login', 'Auth\LoginController@login');
一, 登录(认证)
 
文件 vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php 内:
 
public function login(Request $request)
{
$this->validateLogin($request); //数据验证
 
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) { //爆破保护
$this->fireLockoutEvent($request);
 
return $this->sendLockoutResponse($request);
}
 
$credentials = $this->credentials($request); //获取登录凭证,这里指用email和密码的数组
 
if ($this->guard()->attempt($credentials, $request->has('remember'))) {
return $this->sendLoginResponse($request);
}
 
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
 
return $this->sendFailedLoginResponse($request);
}
 
1. $this->validateLogin($request); 数据验证。
 
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required', 'password' => 'required',
]);
}
 
2. $credentials = $this->credentials($request);
 
protected function credentials(Request $request)
{
return $request->only($this->username(), 'password');
}
public function username()
{
return 'email';
}
3. $this->guard()->attempt($credentials, $request->has('remember')) //进行身份认证
 
这里 $this->guard() 获取系统默认 guard,配置文件 ),对应 Illuminate\Auth\SessionGuardIlluminate\Auth\SessionGuard
文件 vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php 内:
 
public function attempt(array $credentials = [], $remember = false, $login = true)
{
$this->fireAttemptEvent($credentials, $remember, $login); //触发认证事件
 
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
 
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials)) {
if ($login) {
$this->login($user, $remember);
}
 
return true;
}
 
// If the authentication attempt fails we will fire an event so that the user
// may be notified of any suspicious attempts to access their account from
// an unrecognized user. A developer may listen to this event as needed.
if ($login) {
$this->fireFailedEvent($user, $credentials);
}
 
return false;
}
 
3.1 $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
 
这里 $this->provider 是指 Illuminate\Auth\EloquentUserProvider::class 的实例。
 
文件 vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php 内:
 
// 根据认证凭证去查询用户信息,返回 User Model 供 guard 实例进行身份认证
public function retrieveByCredentials(array $credentials)
{
if (empty($credentials)) {//这里的$credentials是指 email和明文密码的数组
return;
}
 
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->createModel()->newQuery();
 
foreach ($credentials as $key => $value) {
if (! Str::contains($key, 'password')) {
$query->where($key, $value);
}
}
 
return $query->first();
}
 
3.2 $this->hasValidCredentials($user, $credentials) 验证密码是否正确!!!
 
文件 vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php 内:
 
protected function hasValidCredentials($user, $credentials)
{
return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
}
 
文件 vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php 内:
 
public function validateCredentials(UserContract $user, array $credentials)
{
$plain = $credentials['password'];
// $plain 明文密码, $user->getAuthPassword() 数据库内保持的hashed 密码
return $this->hasher->check($plain, $user->getAuthPassword());
}
 
Illuminate\Contracts\Hashing\Hasher 接口内:
/**
* Check the given plain value against a hash.
*
* @param string $value
* @param string $hashedValue
* @param array $options
* @return bool
*/
public function check($value, $hashedValue, array $options = []);
 
3.3 $this->login($user, $remember); 见注册部分的说明
 
退出登录
 
文件 vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php 内:
 
public function logout(Request $request)
{
$this->guard()->logout();
 
$request->session()->flush();
 
$request->session()->regenerate();
 
return redirect('/');
}
 
文件 vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php 内:
 
public function logout()
{
$user = $this->user(); // User Model
 
// If we have an event dispatcher instance, we can fire off the logout event
// so any further processing can be done. This allows the developer to be
// listening for anytime a user signs out of this application manually.
$this->clearUserDataFromStorage(); //清除cookie, session
 
if (! is_null($this->user)) {
$this->refreshRememberToken($user); //清除数据库中的 remember_token
}
 
if (isset($this->events)) {
$this->events->fire(new Events\Logout($user));
}
 
// Once we have fired the logout event we will clear the users out of memory
// so they are no longer available as the user is no longer considered as
// being signed into this application and should not be available here.
$this->user = null;
 
$this->loggedOut = true;
}
 
protected function clearUserDataFromStorage()
{
$this->session->remove($this->getName()); //移除session
 
if (! is_null($this->getRecaller())) {
$recaller = $this->getRecallerName();
 
$this->getCookieJar()->queue($this->getCookieJar()->forget($recaller)); //cookie过期
}
}
 
/*清除 remember_token*/
protected function refreshRememberToken(AuthenticatableContract $user)
{
$user->setRememberToken($token = Str::random(60));
$this->provider->updateRememberToken($user, $token); //通过设置一个随机串来清除原 token
}
 
文件 vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php 内:
 
/* Update the "remember me" token for the given user in storage. */
public function updateRememberToken(UserContract $user, $token)
{
$user->setRememberToken($token);
$user->save(); //更新数据库
}
 

Laravel 5.3 登录注册底层实现详解的更多相关文章

  1. Laravel 5.3 auth中间件底层实现详解

    1. 注册认证中间件, 在文件 app/Http/Kernel.php 内完成: protected $routeMiddleware = [ 'auth' => \Illuminate\Aut ...

  2. Laravel 5.3 auth中间件底层实现详解(转)

    1. 注册认证中间件, 在文件 app/Http/Kernel.php 内完成: protected $routeMiddleware = [ 'auth' => \Illuminate\Aut ...

  3. [转帖]Windows注册表内容详解

    Windows注册表内容详解 来源:http://blog.sina.com.cn/s/blog_4d41e2690100q33v.html 对 windows注册表一知半解 不是很清晰 这里学习一下 ...

  4. Windows注册表内容详解

    Windows注册表内容详解 http://blog.sina.com.cn/s/blog_4d41e2690100q33v.html (2011-04-05 10:46:17)   第一课  注册表 ...

  5. Linux ssh登录和软件安装详解

    阿哲Style   Linux第一天 ssh登录和软件安装详解 Linux学习第一天 操作环境: Ubuntu 16.04 Win10系统,使用putty_V0.63 本身学习Linux就是想在服务器 ...

  6. Spring Aop底层原理详解

    Spring Aop底层原理详解(来源于csdn:https://blog.csdn.net/baomw)

  7. Shiro 登录认证源码详解

    Shiro 登录认证源码详解 Apache Shiro 是一个强大且灵活的 Java 开源安全框架,拥有登录认证.授权管理.企业级会话管理和加密等功能,相比 Spring Security 来说要更加 ...

  8. SSH远程登录和端口转发详解

     SSH远程登录和端口转发详解   介绍 SSH 是创建在应用层和传输层基础上的安全协议,为计算机上的 Shell(壳层)提供安全的传输和使用环境. SSH 只是协议,有多种实现方式,本文基于其开源实 ...

  9. Redis底层函数详解

    Redis底层函数详解 serverCron 函数 它负责管理服务器的资源,并维持服务器的正常运行.在执行 serverCron 函数的过程中会调用相关的子函数,如 trackOperationsPe ...

随机推荐

  1. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  2. HTTP协议系列(1)

    一.为什么学习Http协议       首先明白我们为什么学习HTTP协议,也就是说明白HTTP协议的作用.HTTP协议是用于客户端与服务器之间的通讯.明白了HTTP协议的作用也就知道了为什么要学习H ...

  3. C#给PDF文档添加文本和图片页眉

    页眉常用于显示文档的附加信息,我们可以在页眉中插入文本或者图形,例如,页码.日期.公司徽标.文档标题.文件名或作者名等等.那么我们如何以编程的方式添加页眉呢?今天,这篇文章向大家分享如何使用了免费组件 ...

  4. Swift与C#的基础语法比较

    背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对 ...

  5. JavaScript 对象属性介绍

    本篇主要介绍JS中对象的属性,包括:属性的分类.访问方式.检测属性.遍历属性以及属性特性等内容. 目录 1. 介绍:描述属性的命名方式.查找路径以及分类 2. 属性的访问方式:介绍'.'访问方式.'[ ...

  6. 深入理解BFC

    定义 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流和普通流三种.而普通流其实就是指BFC中的FC.FC是formatting context的首字母缩写,直译过来是格式化上 ...

  7. PHP设计模式(二)工厂方法模式(Factory Method For PHP)

    简单工厂简述: 简单工厂模式实现了生产产品类的代码跟客户端代码分离,在工厂类中你可以添加需要生成长跑的逻辑代码(new 产品类),但是问题来了,优秀的代码是符合"开闭原则"如果你要 ...

  8. SharePoint 2013: A feature with ID has already been installed in this farm

    使用Visual Studio 2013创建一个可视web 部件,当右击项目选择"部署"时报错: "Error occurred in deployment step ' ...

  9. 使用Hudson搭建自动构建服务器

    环境: ubuntu1404_x64 说明: 使用hudson和git搭建自动构建服务器的简单示例 安装hudson及相关插件 安装hudson 安装命令如下: sudo sh -c "ec ...

  10. java 字节流与字符流的区别

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作 ...