问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

laravel auth.php怎么配置

发布网友 发布时间:2022-04-07 05:26

我来回答

2个回答

懂视网 时间:2022-04-07 09:47

本文是基于Laravel 5.4 版本的Auth模块代码进行分析书写;

模块组成

Auth模块从功能上分为用户认证和权限管理两个部分;从文件组成上,IlluminateAuthPasswords目录下是密码重置或忘记密码处理的小模块,IlluminateAuth是负责用户认证和权限管理的模块,IlluminateFoundationAuth提供了登录、修改密码、重置密码等一系统列具体逻辑实现;下图展示了Auth模块各个文件的关系,并进行简要说明;

1110086620-599434959f8a2_articlex.jpg

用户认证

HTTP本身是无状态,通常在系统交互的过程中,使用账号或者Token标识来确定认证用户;

配置文件解读

return [
 'defaults' => [
 'guard' => 'web',
 ...
 ],
 'guards' => [ 
 'web' => [
  'driver' => 'session',
  'provider' => 'users',
 ],
 'api' => [ 
  'driver' => 'token', 
  'provider' => 'users',
 ],
 ],
 'providers' => [
 'users' => [
  'driver' => 'eloquent',
  'model' => AppUser::class,
 ], 
 ],
], 
];

从下往上,理解;

providers是提供用户数据的接口,要标注驱动对象和目标对象;此处,键名users是一套provider的名字,采用eloquent驱动,modal是AppUser::class;

guards部分针对认证管理部分进行配置;有两种认证方式,一种叫web,还有一种是api;web认证是基于Session交互,根据sessionId获取用户id,在users这个provider查询出此用户;api认证是基于token值交互,也采用users这个provider;

defaults项显示默认使用web认证;

认证

Session绑定认证信息:

// $credentials数组存放认证条件,比如邮箱或者用户名、密码
// $remember 表示是否要记住,生成 `remember_token`
public function attempt(array $credentials = [], $remember = false) 
 
public function login(AuthenticatableContract $user, $remember = false)
 
public function loginUsingId($id, $remember = false)

HTTP基本认证,认证信息放在请求头部;后面的请求访问通过sessionId;

public function basic($field = 'email', $extraConditions = [])

只在当前会话中认证,session中不记录认证信息:

public function once(array $credentials = [])
public function onceUsingId($id)
public function onceBasic($field = 'email', $extraConditions = [])

认证过程中(包括注册、忘记密码),定义的事件有这些:

Attempting 尝试验证事件

Authenticated 验证通过事件

Failed 验证失败事件

Lockout 失败次数超过限制,锁住该请求再次访问事件

Logi 通过‘remember_token’成功登录时,调用的事件

Logout 用户退出事件

Registered 用户注册事件

还有一些其他的认证方法:

检查是否存在认证用户:Auth::check()

获取当前认证用户:Auth::user()

退出系统:Auth::logout()

密码处理

配置解读

return [
 'defaults' => [
 'passwords' => 'users',
 ...
 ],
 
 'passwords' => [
 'users' => [
  'provider' => 'users',
  'table' => 'password_resets',
  'expire' => 60,
 ],
 ],
]

从下往上,看配置;

passwords数组是重置密码的配置;users是配置方案的别名,包含三个元素:provider(提供用户的方案,是上面providers数组)、table(存放重置密码token的表)、expire(token过期时间)

default 项会设置默认的 passwords 重置方案;

重置密码的调用与实现

先看看Laravel的重置密码功能是怎么实现的:

public function reset(array $credentials, Closure $callback) {
 // 验证用户名、密码和 token 是否有效
 $user = $this->validateReset($credentials);
 if (! $user instanceof CanResetPasswordContract) {
  return $user;
 } 
 
 $password = $credentials['password'];
 // 回调函数执行修改密码,及持久化存储
 $callback($user, $password);
 // 删除重置密码时持久化存储保存的 token
 $this->tokens->delete($user);
 return static::PASSWORD_RESET;
}

再看看FoundationAuth模块封装的重置密码模块是怎么调用的:

// 暴露的重置密码 API
public function reset(Request $request) {
 // 验证请求参数 token、email、password、password_confirmation
 $this->validate($request, $this->rules(), $this->validationErrorMessages());
 // 调用重置密码的方法,第二个参数是回调,做一些持久化存储工作
 $response = $this->broker()->reset(
 $this->credentials($request), function ($user, $password) {
 $this->resetPassword($user, $password);
 }
 );
 // 封装 Response
 return $response == Password::PASSWORD_RESET
 ? $this->sendResetResponse($response)
 : $this->sendResetFailedResponse($request, $response);
}
// 获取重置密码时的请求参数
protected function credentials(Request $request) {
 return $request->only(
 'email', 'password', 'password_confirmation', 'token'
 );
}
// 重置密码的真实性验证后,进行的持久化工作
protected function resetPassword($user, $password) {
 // 修改后的密码、重新生成 remember_token
 $user->forceFill([
 'password' => bcrypt($password),
 'remember_token' => Str::random(60),
 ])->save();
 // session 中的用户信息也进行重新赋值     
 $this->guard()->login($user);
}

“忘记密码 => 发邮件 => 重置密码” 的大体流程如下:

点击“忘记密码”,通过路由配置,跳到“忘记密码”页面,页面上有“要发送的邮箱”这个字段要填写;

验证“要发送的邮箱”是否是数据库中存在的,如果存在,即向该邮箱发送重置密码邮件;

重置密码邮件中有一个链接(点击后会携带 token 到修改密码页面),同时数据库会保存这个 token 的哈希加密后的值;

填写“邮箱”,“密码”,“确认密码”三个字段后,携带 token 访问重置密码API,首页判断邮箱、密码、确认密码这三个字段,然后验证 token是否有效;如果是,则重置成功;

权限管理

权限管理是依靠内存空间维护的一个数组变量abilities来维护,结构如下:

$abilities = array(
 '定义的动作名,比如以路由的 as 名(common.dashboard.list)' => function($user) {
 // 方法的参数,第一位是 $user, 当前 user, 后面的参数可以自行决定
 return true; // 返回 true 意味有权限, false 意味没有权限
 },
 ......
);

但只用 $abilities,会使用定义的那部分代码集中在一起太烦索,所以有policy策略类的出现;

policy策略类定义一组实体及实体权限类的对应关系,比如以文章举例:

有一个 Modal实体类叫 Post,可以为这个实体类定义一个PostPolicy权限类,在这个权限类定义一些动作为方法名;

class PostPolicy {
 // update 权限,文章作者才可以修改
 public function update(User $user, Post $post) {
 return $user->id === $post->user_id;
 }
}

然后在ServiceProvider中注册,这样系统就知道,如果你要检查的类是Post对象,加上你给的动作名,系统会找到PostPolicy类的对应方法;

protected $policies = [
 Post::class => PostPolicy::class,
];

怎么调用呢?

对于定义在abilities数组的权限:

当前用户是否具备common.dashboard.list权限:Gate::allows('common.dashboard.list')

当前用户是否具备common.dashboard.list权限:! Gate::denies('common.dashboard.list')

当前用户是否具备common.dashboard.list权限:$request->user()->can('common.dashboard.list')

当前用户是否具备common.dashboard.list权限:! $request->user()->cannot('common.dashboard.list')

指定用户是否具备common.dashboard.list权限:Gate::forUser($user)->allows('common.dashboard.list')

对于policy策略类调用的权限:

当前用户是否可以修改文章(Gate 调用):Gate::allows('update', $post)

当前用户是否可以修改文章(user 调用):$user->can('update', $post)

当前用户是否可以修改文章(用帮助函数):policy($post)->update($user, $post)

当前用户是否可以修改文章(Controller 类方法中调用):$this->authorize('update', $post);

当前用户是否可以修改文章(Controller 类同名方法中调用):$this->authorize($post);

指定用户是否可以修改文章(Controller 类方法中调用):$this->authorizeForUser($user, 'update', $post);

有用的技巧

获取当前系统注册的权限,包括两部分abilities和policies数组内容,代码如下:

$gate = app(IlluminateContractsAuthAccessGate::class);
$reflection_gate = new ReflectionClass($gate);
$policies = $reflection_gate->getProperty('policies');
$policies->setAccessible(true);
// 获取当前注册的 policies 数组
dump($policies->getValue($gate));
             
$abilities = $reflection_gate->getProperty('abilities');     
$abilities->setAccessible(true);
// 获取当前注册的 abilities 数组
dump($abilities->getValue($gate));

推荐教程:《Laravel教程》

热心网友 时间:2022-04-07 06:55

public function login(UserContract $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);

$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);
}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
这是什么钞票。 请问这是哪个国家的钞票?价值多少人民币?谢谢 快易典学生平板电脑屏幕碎了怎么办,我在书店买的,可以拿到书店修吗... 沧州龟头周围有一圈小肉粒是什么? 快易典学生电脑的屏幕摔坏了,触屏触不了,可以修吗?如果修的话要多少... 西班牙冷汤和哪些菜品搭配更好喝? 西班牙番茄冷汤提示 我想请问你在秦汉胡同学学古筝...一共需要多少钱啊,包括买古筝的钱 word2010如何查看和编辑文档? 胸罩带子老掉,罩杯边有空 红米4A,就是599元的那个有nfc功能吗? 关于化学检验硫酸及可溶性硫酸盐的问题。 怎么样检验硫酸与硫酸盐 硫酸盐的鉴别反应 硫酸盐 硝酸盐 胺盐是什么? 什么是硫酸盐 硫酸盐是什么 硫酸根跟硫酸盐的区别 实验室中如何检验硫酸和硫酸盐 硫酸盐的化学方程式怎么写 硫酸盐是怎样形成的? 苹果手机apple pay怎么绑定储蓄卡 硫酸盐有哪些 西装与羊毛衫怎样搭配? 硫酸盐化学式是什么? 鉴别硫酸和硫酸盐为什么要加入硝酸 怎样鉴别硫酸和硫酸盐 苹果手机怎么绑定银行卡刷地铁 半袖羊毛衫怎么搭配最好? 硫酸盐是什么? 手机开不了机但是屏幕一直闪怎么办? 昆明理工大学是本一还是本二? 昆明理工大学的校内环境是怎样的?学习氛围舒适度又如何? 昆明理工大学高职本科和昆明理工大学毕业证有没有区别?区别在哪里? 2022届考研考生,本科是昆明理工大学汉语国际教育专业,研究生很纠结是考到云大还是云师大?云大是2_百度问一问 “昆明理工大学高等职业教育普通本科”是个什么概念? laravel 5.1版本中为什么移除了Auth 小米手机怎么看内存还剩多少 路虎发现5试驾车可以买吗? 路虎发现5什么颜色最好 为什么这么多人黑路虎?路虎有哪些优缺点? 路虎发现五哪个颜色搭配好看 2021款路虎发现正式上市,这款车究竟有哪些亮点? 全新路虎发现运动版云上市 售35.68万元起 路虎发现5行车电脑上怎么看电瓶状态? 路虎发现运动版到店看车试驾,豪华SUV的越野强者 路虎发现运动版配置曝光:2.0T+9AT+48V微混,入门配ACC/泊车辅助 路虎发现5冷冻液是粉红色还是橘红色还是红色? Laravel 5.0的自带的Auth和七牛云的包 Qiniu\Auth产生冲突怎么办 obv水上漂选股公式