每个控制器都使用 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 auth中间件底层实现详解
1. 注册认证中间件, 在文件 app/Http/Kernel.php 内完成: protected $routeMiddleware = [ 'auth' => \Illuminate\Aut ...
- Laravel 5.3 auth中间件底层实现详解(转)
1. 注册认证中间件, 在文件 app/Http/Kernel.php 内完成: protected $routeMiddleware = [ 'auth' => \Illuminate\Aut ...
- [转帖]Windows注册表内容详解
Windows注册表内容详解 来源:http://blog.sina.com.cn/s/blog_4d41e2690100q33v.html 对 windows注册表一知半解 不是很清晰 这里学习一下 ...
- Windows注册表内容详解
Windows注册表内容详解 http://blog.sina.com.cn/s/blog_4d41e2690100q33v.html (2011-04-05 10:46:17) 第一课 注册表 ...
- Linux ssh登录和软件安装详解
阿哲Style Linux第一天 ssh登录和软件安装详解 Linux学习第一天 操作环境: Ubuntu 16.04 Win10系统,使用putty_V0.63 本身学习Linux就是想在服务器 ...
- Spring Aop底层原理详解
Spring Aop底层原理详解(来源于csdn:https://blog.csdn.net/baomw)
- Shiro 登录认证源码详解
Shiro 登录认证源码详解 Apache Shiro 是一个强大且灵活的 Java 开源安全框架,拥有登录认证.授权管理.企业级会话管理和加密等功能,相比 Spring Security 来说要更加 ...
- SSH远程登录和端口转发详解
SSH远程登录和端口转发详解 介绍 SSH 是创建在应用层和传输层基础上的安全协议,为计算机上的 Shell(壳层)提供安全的传输和使用环境. SSH 只是协议,有多种实现方式,本文基于其开源实 ...
- Redis底层函数详解
Redis底层函数详解 serverCron 函数 它负责管理服务器的资源,并维持服务器的正常运行.在执行 serverCron 函数的过程中会调用相关的子函数,如 trackOperationsPe ...
随机推荐
- SQL Server技术内幕笔记合集
SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...
- Java中的多态
1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal {public abstract void Say();} 子类: public class ...
- 【Win 10 应用开发】启动远程设备上的应用
这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...
- 用html5的canvas和JavaScript创建一个绘图程序
本文将引导你使用canvas和JavaScript创建一个简单的绘图程序. 创建canvas元素 首先准备容器Canvas元素,接下来所有的事情都会在JavaScript里面. <canvas ...
- Android注解使用之注解编译android-apt如何切换到annotationProcessor
前言: 自从EventBus 3.x发布之后其通过注解预编译的方式解决了之前通过反射机制所引起的性能效率问题,其中注解预编译所采用的的就是android-apt的方式,不过最近Apt工具的作者宣布了不 ...
- app引导页(背景图片切换加各个页面动画效果)
前言:不知不觉中又加班到了10点半,整个启动页面做了一天多的时间,一共有三个页面,每个页面都有动画效果,动画效果调试起来麻烦,既要跟ios统一,又要匹配各种不同的手机,然后产品经理还有可能在中途改需求 ...
- 简记某WebGIS项目的优化之路
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1. 背景 该项目为研究生时的老师牵头,个人已毕业数年,应老师要求协助其 ...
- 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范
昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...
- SQL Server2008R2 在windows8上安装,出现“兼容性”和 “执行未经授权的操作”的错误!
本人是windows8.1的操作系统,亲测安装成功 解决方法如下: 1.卸载干净sql Server2008r2,包括注册表内容,删除c盘下的安装路径! 2.关闭防火墙(这步很重要) 3.断开网络连接 ...
- GJM : C#设计模式汇总整理——导航 【原创】
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...