每个控制器都使用 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. 游戏编程系列[1]--游戏编程中RPC协议的使用[3]--体验

    运行环境,客户端一般编译为.Net 3.5 Unity兼容,服务端因为用了一些库,所以一般为4.0 或往上.同一份代码,建立拥有2个项目.客户端引用: WindNet.Client服务端引用: OpL ...

  2. JavaScript之链式结构序列化

    一.概述 在JavaScript中,链式模式代码,太多太多,如下: if_else: if(...){ //TODO }else if(...){ //TODO }else{ //TODO } swi ...

  3. Android如何制作漂亮的自适布局的键盘

    最近做了个自定义键盘,但面对不同分辨率的机型其中数字键盘不能根据界面大小自已铺满,但又不能每种机型都做一套吧,所以要做成自适应,那这里主讲思路. 这里最上面的titlebar高度固定,下面输入的金额高 ...

  4. bzoj1901--树状数组套主席树

    树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...

  5. cesium自定义气泡窗口infoWindow

    一.自定义气泡窗口与cesium默认窗口效果对比: 1.cesium点击弹出气泡窗口显示的位置固定在地图的右上角,默认效果: 2.对于习惯arcgis或者openlayer气泡窗口样式的giser来说 ...

  6. 【干货分享】流程DEMO-出差申请单

    流程名: 出差申请  业务描述: 员工出差前发起流程申请,流程发起时,会检查预算,如果预算不够,将不允许发起费用申请,如果预算够用,将发起流程,同时占用相应金额的预算,但撤销流程会释放相应金额的预算. ...

  7. SSH免手动输入密码和设置代理

    通过使用sshpass将密码写入命令里,直接执行,免去手动密码输入的步骤命令如下: sshpass -p password_abc ssh user_abc@ssh_host -p ssh_port ...

  8. ReSharper详解Index0

    JetBrains ReSharper可以帮助Visual Studio用户编写出更好的代码.支持对C#,VB.NET,XAML,JavaScript,TypeScript,JSON,XML,HTML ...

  9. Linux下部署ASP.NET服务连接oracle遇到的问题记录

    一.如何卸载MONO Q:mono是linux系统上跨平台软件,卸载它有两种方式: 1.知道mono安装路径,安装原来的路径直接覆盖安装(最为简单): 2.不知道mono安装路径,首先通过sudo f ...

  10. Web API 入门指南 - 闲话安全

    Web API入门指南有些朋友回复问了些安全方面的问题,安全方面可以写的东西实在太多了,这里尽量围绕着Web API的安全性来展开,介绍一些安全的基本概念,常见安全隐患.相关的防御技巧以及Web AP ...