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开发大型项目的一点经验
Oct 09 PHP
一个odbc连mssql分页的类
Oct 09 PHP
如何限制访问者的ip(PHPBB的代码)
Oct 09 PHP
PHP 如何向 MySQL 发送数据
Oct 09 PHP
discuz程序的PHP加密函数原理分析
Aug 05 PHP
使用php+Ajax实现唯一校验实现代码[简单应用]
Nov 29 PHP
下拉列表多级联动dropDownList示例代码
Jun 27 PHP
PHP中多维数组的foreach遍历示例
Jun 13 PHP
PHP使用逆波兰式计算工资的方法
Jul 29 PHP
PHP实现基于文本的摩斯电码生成器
Jan 11 PHP
Symfony2针对输入时间进行查询的方法分析
Jun 28 PHP
laravel 5.5 关闭token的3种实现方式
Oct 24 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中的CMS的涵义
2007/03/11 PHP
PHP 读取和修改大文件的某行内容的代码
2009/10/30 PHP
js 日期转换成中文格式的函数
2009/07/07 Javascript
jQuery判断元素是否是隐藏的代码
2011/04/24 Javascript
js 关键词高亮(根据ID/tag高亮关键字)案例介绍
2013/01/21 Javascript
含有CKEditor的表单如何提交
2014/01/09 Javascript
JavaScript中创建对象和继承示例解读
2014/02/12 Javascript
jQuery实现个性翻牌效果导航菜单的方法
2015/03/09 Javascript
JavaScript去除数组里重复值的方法
2015/07/13 Javascript
js日期插件dateHelp获取本月、三个月、今年的日期
2016/03/07 Javascript
JS获取随机数和时间转换的简单实例
2016/07/10 Javascript
基于EasyUI的基础之上实现树形功能菜单
2017/06/28 Javascript
如何利用@angular/cli V6.0直接开发PWA应用详解
2018/05/06 Javascript
webpack4.x开发环境配置详解
2018/08/04 Javascript
ndm:NPM的桌面GUI应用程序
2018/10/15 Javascript
使用vue完成微信公众号网页小记(推荐)
2019/04/28 Javascript
[40:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Liquid vs TNC
2018/04/01 DOTA
[02:49]2018DOTA2亚洲邀请赛主赛事决赛日战况回顾 Mineski鏖战5局夺得辉耀
2018/04/10 DOTA
[01:02:47]EG vs Secret 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
python远程登录代码
2008/04/29 Python
Python 列表list使用介绍
2014/11/30 Python
Python之web模板应用
2017/12/26 Python
Python实现自定义顺序、排列写入数据到Excel的方法
2018/04/23 Python
Python批处理更改文件名os.rename的方法
2018/10/26 Python
Pytorch加载部分预训练模型的参数实例
2019/08/18 Python
如何使用Django Admin管理后台导入CSV
2020/11/06 Python
Python LMDB库的使用示例
2021/02/14 Python
程序设计HTML5 Canvas API
2013/04/08 HTML / CSS
ALDI奥乐齐官方海外旗舰店:德国百年超市
2017/12/27 全球购物
四风对照检查材料范文
2014/09/27 职场文书
四风问题党员个人整改措施
2014/10/27 职场文书
放弃遗产继承公证书
2015/01/26 职场文书
500字作文之关于爸爸
2019/11/14 职场文书
tensorflow学习笔记之tfrecord文件的生成与读取
2021/03/31 Python
防止web项目中的SQL注入
2021/12/06 MySQL
HTML5之高度塌陷问题的解决
2022/06/01 HTML / CSS