每个控制器都使用 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. 使用etree.HTML的编码问题

    title: 使用etree.HTML的编码问题 date: 2015-10-07 17:56:47 categories: [Python] tags: [Python, lxml, Xpath] ...

  2. WPF做12306验证码点击效果

    一.效果 和12306是一样的,运行一张图上点击多个位置,横线以上和左边框还有有边框位置不允许点击,点击按钮输出坐标集合,也就是12306登陆的时候,需要向后台传递的参数. 二.实现思路 1.获取验证 ...

  3. Intel Media SDK H264 encoder GOP setting

    1 I帧,P帧,B帧,IDR帧,NAL单元 I frame:帧内编码帧,又称intra picture,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随 ...

  4. C#创建dll类库

    类库让我们的代码可复用,我们只需要在类库中声明变量一次,就能在接下来的过程中无数次地使用,而无需在每次使用前都要声明它.这样一来,就节省了我们的内存空间.而想要在类库添加什么类,还需取决于类库要实现哪 ...

  5. angularjs 依赖注入--自己学着实现

    在用angular依赖注入时,感觉很好用,他的出现是 为了"削减计算机程序的耦合问题" ,我怀着敬畏与好奇的心情,轻轻的走进了angular源码,看看他到底是怎么实现的,我也想写个 ...

  6. 【绝对干货】仿微信QQ设置图形头像裁剪,让你的App从此炫起来~

    最近在做毕业设计,想有一个功能和QQ一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流. 而纵观现在主流的APP,只要有用户系统这个功能,这个需求一般都是在(bu)劫(de)难(bu)逃(xue ...

  7. sql的那些事(一)

    一.概述 书写sql是我们程序猿在开发中必不可少的技能,优秀的sql语句,执行起来吊炸天,性能杠杠的.差劲的sql,不仅使查询效率降低,维护起来也十分不便.一切都是为了性能,一切都是为了业务,你觉得你 ...

  8. PHP设计模式(七)适配器模式(Adapter For PHP)

    适配器模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 如下图(借图): // 设置书的接口 // 书接口 interface BookI ...

  9. 纯javaScript、jQuery实现个性化图片轮播

    纯javaScript实现个性化图片轮播 轮播原理说明<如上图所示>: 1. 画布部分(可视区域)属性说明:overflow:hidden使得超出画布部分隐藏或说不可见.position: ...

  10. 如何使用本地账户"完整"安装 SharePoint Server 2010+解决“New-SPConfigurationDatabase : 无法连接到 SharePoint_Config 的 SQL Server 的数据 库 master。此数据库可能不存在,或当前用户没有连接权限。”

    注:目前看到的解决本地账户完整安装SharePoint Server 2010的解决方案如下,但是,有但是的哦: 当我们选择了"完整"模式安装SharePointServer201 ...