Laravel的Auth验证Token验证使用自定义Redis的例子


Posted in PHP onSeptember 30, 2019

背景

项目用户量逐渐增大,接口调用次数越来越多,所以决定使用Redis存token,缓解数据库压力

调研

config/auth.php文件中发现用户的驱动使用的是EloquentUserProvider服务提供器,然后查找EloquentUserProvider.php 然后发现在vendor/laravel/framework/src/Illuminate/Auth文件下存在该文件

<?php
 
namespace Illuminate\Auth;
 
use Illuminate\Support\Str;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
 
class EloquentUserProvider implements UserProvider
{
 /**
  * The hasher implementation.
  *
  * @var \Illuminate\Contracts\Hashing\Hasher
  */
 protected $hasher;
 
 /**
  * The Eloquent user model.
  *
  * @var string
  */
 protected $model;
 
 /**
  * Create a new database user provider.
  *
  * @param \Illuminate\Contracts\Hashing\Hasher $hasher
  * @param string $model
  * @return void
  */
 public function __construct(HasherContract $hasher, $model)
 {
  $this->model = $model;
  $this->hasher = $hasher;
 }
 
 /**
  * Retrieve a user by their unique identifier.
  *
  * @param mixed $identifier
  * @return \Illuminate\Contracts\Auth\Authenticatable|null
  */
 public function retrieveById($identifier)
 {
  return $this->createModel()->newQuery()->find($identifier);
 }
 ...
  /**
  * Retrieve a user by the given credentials.
  *
  * @param array $credentials
  * @return \Illuminate\Contracts\Auth\Authenticatable|null
  */
 public function retrieveByCredentials(array $credentials)
 {
  if (empty($credentials)) {
   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();
 }
...
}

实现代码

因为我们是需要在当前的Auth验证基础之上添加一层Redis缓存,所以最简单的办法继承EloquentUserProvider类,重写

retrieveByCredentials方法所以我们新建RedisUserProvider.php文件

<?php
namespace App\Providers;
 
use Illuminate\Auth\EloquentUserProvider;
use Cache;
 
class RedisUserProvider extends EloquentUserProvider
{
 
 public function __construct($hasher, $model)
 {
  parent::__construct($hasher, $model);
 }
 /**
  * Retrieve a user by the given credentials.
  *
  * @param array $credentials
  * @return \Illuminate\Contracts\Auth\Authenticatable|null
  */
 public function retrieveByCredentials(array $credentials)
 {
 
  if (!isset($credentials['token'])) {
   return;
  }
 
  $token = $credentials['token'];
  $redis = Cache::getRedis();
  $userId = $redis->get($token);
  
  return $this->retrieveById($userId);
 }
}

然后在AuthServiceProvider.php文件下修改如下代码

public function boot(GateContract $gate)
 {
  $this->registerPolicies($gate);
 
  //将redis注入Auth中
  Auth::provider('redis',function($app, $config){
   return new RedisUserProvider($app['hash'], $config['model']);
  });
 }

修改config/auth.php用户的auth的驱动为redis。

后续

改完代码以后发现无法正常登录,一直提示用户或密码错误。。。然后看看了下用户认证方法是

auth('web')->once($credentials);然后看是在
Illuminate\Auth\SessionGuard文件中用到了RedisUserProvider文件中retrieveByCredentials方法中对用户进行密码验证,

于是修改RedisUserProvider文件

<?php
namespace App\Providers;
 
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Support\Str;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Cache;
 
class RedisUserProvider extends EloquentUserProvider
{
 
 public function __construct($hasher, $model)
 {
  parent::__construct($hasher, $model);
 }
 /**
  * Retrieve a user by the given credentials.
  *
  * @param array $credentials
  * @return \Illuminate\Contracts\Auth\Authenticatable|null
  */
 public function retrieveByCredentials(array $credentials)
 {
 
  if (empty($credentials)) {
   return;
  }
  if(isset($credentials['phone']) && isset($credentials['password'])){
   // 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();
  }
 
  $token = $credentials['token'];
  $redis = Cache::getRedis();
  $userId = $redis->get($token);
 
  return $this->retrieveById($userId);
 }
}

然后登录成功啦!皆大欢喜!

以上这篇Laravel的Auth验证Token验证使用自定义Redis的例子就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
随时给自己贴的图片加文字的php代码
Mar 08 PHP
php中获取指定IP的物理地址的代码(正则表达式)
Jun 23 PHP
PHP清除数组中所有字符串两端空格的方法
Oct 20 PHP
PHP原生函数一定好吗?
Dec 08 PHP
php生成excel列名超过26列大于Z时的解决方法
Dec 29 PHP
使用新浪微博API的OAuth认证发布微博实例
Mar 27 PHP
php通过curl模拟登陆DZ论坛
May 11 PHP
PHP模板引擎Smarty中的保留变量用法分析
Apr 11 PHP
php查询及多条件查询
Feb 26 PHP
php封装db类连接sqlite3数据库的方法实例
Dec 19 PHP
PHP自动识别当前使用移动终端
May 21 PHP
php实现微信公众号企业转账功能
Oct 01 PHP
Laravel框架控制器的middleware中间件用法分析
Sep 30 #PHP
Laravel 已登陆用户再次查看登陆页面的自动跳转设置方法
Sep 30 #PHP
laravel实现登录时监听事件,添加登录用户的记录方法
Sep 30 #PHP
php7下的filesize函数
Sep 30 #PHP
laravel利用中间件防止未登录用户直接访问后台的方法
Sep 30 #PHP
laravel实现Auth认证,登录、注册后的页面回跳方法
Sep 30 #PHP
Laravel框架表单验证操作实例分析
Sep 30 #PHP
You might like
PHP默认安装产生系统漏洞
2006/10/09 PHP
PHP 上传文件的方法(类)
2009/07/30 PHP
PHP的autoload自动加载机制使用说明
2010/12/28 PHP
php中将网址转换为超链接的函数
2011/09/02 PHP
php格式化电话号码的方法
2015/04/24 PHP
php curl中gzip的压缩性能测试实例分析
2016/11/08 PHP
Zend Framework动作控制器用法示例
2016/12/09 PHP
js 判断图片是否加载完以及实现图片的预下载
2014/08/14 Javascript
js实现的彩色方块飞舞奇幻效果
2016/01/27 Javascript
HTML页面,测试JS对C函数的调用简单实例
2016/08/09 Javascript
微信小程序 实现tabs选项卡效果实例代码
2016/10/31 Javascript
简单理解js的冒泡排序
2016/12/19 Javascript
详解VUE的状态控制与延时加载刷新
2017/03/27 Javascript
mint-ui的search组件在键盘显示搜索按钮的实现方法
2017/10/27 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
JS拖动选择table里的单元格完整实例【基于jQuery】
2019/05/28 jQuery
微信小程序实现左滑删除效果
2020/11/18 Javascript
Python实现将目录中TXT合并成一个大TXT文件的方法
2015/07/15 Python
Python的MongoDB模块PyMongo操作方法集锦
2016/01/05 Python
Python数组遍历的简单实现方法小结
2016/04/27 Python
python制作websocket服务器实例分享
2016/11/20 Python
python输出100以内的质数与合数实例代码
2018/07/08 Python
vscode 配置 python3开发环境的方法
2019/09/19 Python
Python使用urllib模块对URL网址中的中文编码与解码实例详解
2020/02/18 Python
python GUI库图形界面开发之PyQt5中QWebEngineView内嵌网页与Python的数据交互传参详细方法实例
2020/02/26 Python
英国汽车座椅和婴儿车购物网站:Uber Kids
2017/04/19 全球购物
美国顶级水上运动专业店:Marine Products
2018/04/15 全球购物
递归计算如下递归函数的值(斐波拉契)
2012/02/04 面试题
空中乘务员岗位职责
2014/03/08 职场文书
销售提升方案
2014/06/07 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话全文
2014/10/25 职场文书
党员违纪检讨书怎么写
2014/11/01 职场文书
高三毕业感言
2015/07/30 职场文书
nginx 多个location转发任意请求或访问静态资源文件的实现
2021/03/31 Servers
python实现简易自习室座位预约系统
2021/06/30 Python
Mysql 一主多从的部署
2022/05/20 MySQL