背景
项目用户量逐渐增大,接口调用次数越来越多,所以决定使用Redis存token,缓解数据库压力
调研
在config/auth.php文件中发现用户的驱动使用的是EloquentUserProvider服务提供器,然后查找EloquentUserProvider.php 然后发现在vendor/laravel/framework/src/Illuminate/Auth文件下存在该文件
代码语言:javascript复制<?php
namespace IlluminateAuth;
use IlluminateSupportStr;
use IlluminateContractsAuthUserProvider;
use IlluminateContractsHashingHasher as HasherContract;
use IlluminateContractsAuthAuthenticatable as UserContract;
class EloquentUserProvider implements UserProvider
{
/**
* The hasher implementation.
*
* @var IlluminateContractsHashingHasher
*/
protected $hasher;
/**
* The Eloquent user model.
*
* @var string
*/
protected $model;
/**
* Create a new database user provider.
*
* @param IlluminateContractsHashingHasher $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 IlluminateContractsAuthAuthenticatable|null
*/
public function retrieveById($identifier)
{
return $this- createModel()- newQuery()- find($identifier);
}
...
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return IlluminateContractsAuthAuthenticatable|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文件
代码语言:javascript复制<?php
namespace AppProviders;
use IlluminateAuthEloquentUserProvider;
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 IlluminateContractsAuthAuthenticatable|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文件下修改如下代码
代码语言:javascript复制 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。
后续
改完代码以后发现无法正常登录,一直提示用户或密码错误。。。然后看看了下用户认证方法是
代码语言:javascript复制auth('web')- once($credentials);然后看是在
代码语言:javascript复制IlluminateAuthSessionGuard文件中用到了RedisUserProvider文件中retrieveByCredentials方法中对用户进行密码验证,
于是修改RedisUserProvider文件
代码语言:javascript复制<?php
namespace AppProviders;
use IlluminateAuthEloquentUserProvider;
use IlluminateSupportStr;
use IlluminateContractsAuthAuthenticatable 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 IlluminateContractsAuthAuthenticatable|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的例子就是小编分享给大家的全部内容了,希望能给大家一个参考。