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 相关文章推荐
福利彩票幸运号码自动生成器
Oct 09 PHP
在php MYSQL中插入当前时间
Apr 06 PHP
在PHP中检查PHP文件是否有语法错误的方法
Dec 23 PHP
用php简单实现加减乘除计算器
Jan 06 PHP
PHP中可以自动分割查询字符的Parse_str函数使用示例
Jul 25 PHP
PHP中Fatal error session_start()错误解决步骤
Aug 05 PHP
PHP实现全角字符转为半角方法汇总
Jul 09 PHP
教你在PHPStorm中配置Xdebug
Jul 27 PHP
PHP根据session与cookie用户登录状态操作类的代码
May 13 PHP
php使用include 和require引入文件的区别
Feb 16 PHP
PHP实现的简单异常处理类示例
May 04 PHP
PHP框架自动加载类文件原理详解
Jun 06 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/11/25 PHP
PHP Curl模拟登录微信公众平台、新浪微博实例代码
2016/01/28 PHP
php微信公众号开发(3)php实现简单微信文本通讯
2016/12/15 PHP
jquery之empty()与remove()区别说明
2010/09/10 Javascript
jQuery技巧总结
2011/01/01 Javascript
High Performance JavaScript(高性能JavaScript)读书笔记分析
2011/05/05 Javascript
清除div下面的所有标签的方法
2014/02/17 Javascript
JavaScript关闭当前页面(窗口)不带任何提示
2014/03/26 Javascript
Js保留小数点的4种效果实现代码分享
2014/04/12 Javascript
node.js中的fs.unlinkSync方法使用说明
2014/12/15 Javascript
node.js实现爬虫教程
2020/08/25 Javascript
AngularJS入门教程一:路由用法初探
2017/05/27 Javascript
jQuery 操作 HTML 元素和属性的方法
2018/11/12 jQuery
实用Javascript调试技巧分享(小结)
2019/06/18 Javascript
使用layui日期控件laydate对开始和结束时间进行联动控制的方法
2019/09/06 Javascript
JavaScript Dom 绑定事件操作实例详解
2019/10/02 Javascript
详解Vue的watch中的immediate与watch是什么意思
2019/12/30 Javascript
python 自动提交和抓取网页
2009/07/13 Python
Python入门篇之正则表达式
2014/10/20 Python
Python中每次处理一个字符的5种方法
2015/05/21 Python
Python实现多线程HTTP下载器示例
2017/02/11 Python
MAC中PyCharm设置python3解释器
2017/12/15 Python
python tensorflow学习之识别单张图片的实现的示例
2018/02/09 Python
python3实现基于用户的协同过滤
2018/05/31 Python
Python Web版语音合成实例详解
2019/07/16 Python
django数据关系一对多、多对多模型、自关联的建立
2019/07/24 Python
wordpress添加Html5的表单验证required方法小结
2020/08/18 HTML / CSS
美国名牌香水折扣网站:Hottperfume
2021/02/10 全球购物
促销活动方案模板
2014/02/24 职场文书
给全校老师的建议书
2014/03/13 职场文书
放飞梦想演讲稿600字
2014/08/26 职场文书
党员违纪检讨书怎么写
2014/11/01 职场文书
离职信范本
2015/06/23 职场文书
公安干警正风肃纪心得体会
2016/01/15 职场文书
互联网的下一个风口:新的独角兽将诞生
2019/08/02 职场文书
Nginx反向代理配置的全过程记录
2021/06/22 Servers