当前位置:首页 > CMS教程 > 其它CMS > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2021-12-25 16:22:32 浏览: 评论:0 

今天小编就为大家分享一篇Laravel的Auth验证Token验证使用自定义Redis的例子,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧。

背景

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

调研

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

  1. <?php 
  2.    
  3. namespace Illuminate\Auth; 
  4.    
  5. use Illuminate\Support\Str; 
  6. use Illuminate\Contracts\Auth\UserProvider; 
  7. use Illuminate\Contracts\Hashing\Hasher as HasherContract; 
  8. use Illuminate\Contracts\Auth\Authenticatable as UserContract; 
  9.    
  10. class EloquentUserProvider implements UserProvider 
  11. { 
  12.  /** 
  13.   * The hasher implementation. 
  14.   * 
  15.   * @var \Illuminate\Contracts\Hashing\Hasher 
  16.   */ 
  17.  protected $hasher; 
  18.    
  19.  /** 
  20.   * The Eloquent user model. 
  21.   * 
  22.   * @var string 
  23.   */ 
  24.  protected $model; 
  25.    
  26.  /** 
  27.   * Create a new database user provider. 
  28.   * 
  29.   * @param \Illuminate\Contracts\Hashing\Hasher $hasher 
  30.   * @param string $model 
  31.   * @return void 
  32.   */ 
  33.  public function __construct(HasherContract $hasher, $model) 
  34.  { 
  35.   $this->model = $model; 
  36.   $this->hasher = $hasher; 
  37.  } 
  38.    
  39.  /** 
  40.   * Retrieve a user by their unique identifier. 
  41.   * 
  42.   * @param mixed $identifier 
  43.   * @return \Illuminate\Contracts\Auth\Authenticatable|null 
  44.   */ 
  45.  public function retrieveById($identifier) 
  46.  { 
  47.   return $this->createModel()->newQuery()->find($identifier); 
  48.  } 
  49.  ... 
  50.   /** 
  51.   * Retrieve a user by the given credentials. 
  52.   * 
  53.   * @param array $credentials 
  54.   * @return \Illuminate\Contracts\Auth\Authenticatable|null 
  55.   */ 
  56.  public function retrieveByCredentials(array $credentials) 
  57.  { 
  58.   if (emptyempty($credentials)) { 
  59.    return; 
  60.   } 
  61.    
  62.   // First we will add each credential element to the query as a where clause. 
  63.   // Then we can execute the query and, if we found a user, return it in a 
  64.   // Eloquent User "model" that will be utilized by the Guard instances. 
  65.   $query = $this->createModel()->newQuery(); 
  66.    
  67.   foreach ($credentials as $key => $value) { 
  68.    if (! Str::contains($key, 'password')) { 
  69.     $query->where($key, $value); 
  70.    } 
  71.   } 
  72.    
  73.   return $query->first(); 
  74.  } 
  75. ... 
  76. } 

实现代码

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

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

  1. <?php 
  2. namespace App\Providers; 
  3.    
  4. use Illuminate\Auth\EloquentUserProvider; 
  5. use Cache; 
  6.    
  7. class RedisUserProvider extends EloquentUserProvider 
  8. { 
  9.    
  10.  public function __construct($hasher, $model) 
  11.  { 
  12.   parent::__construct($hasher, $model); 
  13.  } 
  14.  /** 
  15.   * Retrieve a user by the given credentials. 
  16.   * 
  17.   * @param array $credentials 
  18.   * @return \Illuminate\Contracts\Auth\Authenticatable|null 
  19.   */ 
  20.  public function retrieveByCredentials(array $credentials) 
  21.  { 
  22.    
  23.   if (!isset($credentials['token'])) { 
  24.    return; 
  25.   } 
  26.    
  27.   $token = $credentials['token']; 
  28.   $redis = Cache::getRedis(); 
  29.   $userId = $redis->get($token); 
  30.     
  31.   return $this->retrieveById($userId); 
  32.  } 
  33. } 

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

  1. public function boot(GateContract $gate) 
  2. { 
  3.  $this->registerPolicies($gate); 
  4.  
  5.  //将redis注入Auth中 
  6.  Auth::provider('redis',function($app, $config){ 
  7.   return new RedisUserProvider($app['hash'], $config['model']); 
  8.  }); 
  9. } 

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

后续

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

auth('web')->once($credentials);然后看是在

Illuminate\Auth\SessionGuard文件中用到了RedisUserProvider文件中retrieveByCredentials方法中对用户进行密码验证,

于是修改RedisUserProvider文件

  1. <?php 
  2. namespace App\Providers; 
  3.    
  4. use Illuminate\Auth\EloquentUserProvider; 
  5. use Illuminate\Support\Str; 
  6. use Illuminate\Contracts\Auth\Authenticatable as UserContract; 
  7. use Cache; 
  8.    
  9. class RedisUserProvider extends EloquentUserProvider 
  10. { 
  11.    
  12.  public function __construct($hasher, $model) 
  13.  { 
  14.   parent::__construct($hasher, $model); 
  15.  } 
  16.  /** 
  17.   * Retrieve a user by the given credentials. 
  18.   * 
  19.   * @param array $credentials 
  20.   * @return \Illuminate\Contracts\Auth\Authenticatable|null 
  21.   */ 
  22.  public function retrieveByCredentials(array $credentials) 
  23.  { 
  24.    
  25.   if (emptyempty($credentials)) { 
  26.    return; 
  27.   } 
  28.   if(isset($credentials['phone']) && isset($credentials['password'])){ 
  29.    // First we will add each credential element to the query as a where clause. 
  30.    // Then we can execute the query and, if we found a user, return it in a 
  31.    // Eloquent User "model" that will be utilized by the Guard instances. 
  32.    $query = $this->createModel()->newQuery(); 
  33.    
  34.    foreach ($credentials as $key => $value) { 
  35.     if (! Str::contains($key, 'password')) { 
  36.      $query->where($key, $value); 
  37.     } 
  38.    } 
  39.    
  40.    return $query->first(); 
  41.   } 
  42.    
  43.   $token = $credentials['token']; 
  44.   $redis = Cache::getRedis(); 
  45.   $userId = $redis->get($token); 
  46.    
  47.   return $this->retrieveById($userId); 
  48.  } 
  49. } 

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

Tags: Laravel验证 Token验证 Redis

分享到: