Lumen 中,如何为 JWT-AUTH 用到的 EloquentUserProvider 加上 Redis 缓存?
业务背景:
开发一个api登录获取JWT的接口,该接口预期秒每并发登录获取token会达到100+请求且每个用户很可能会不断的获取TOKEN (请不要让我对其做限制,这是业务允许的行为)
准备使用的包
jwt-auth lumen dingoapi https://github.com/liyu001989/lumen-api-de...**
过程:
因为对laravel和lumen都不是很熟悉,所以不太清楚Auth的整个验证过程,安装完lumen api demo后,我开始跟代码,\Auth::attempt([用户名,密码]),发现它最后执行的文件是vendor/tymon/jwt-auth/src/JWTGuard.php 中的attempt,它是通过调用hasValidCredenitals进行验证的,继续跟
protected function hasValidCredentials($user, $credentials)
{ dd($user); ====> null (发现$user是NULL值)
return $user !== null && $this->provider->validateCredentials($user, $credentials);
}
我直接点击 validateCredentials 得到的是一个接口类,通过搜索找到validateCredentials实际执行的位置在
vendor/illuminate/auth/EloquentUserProvider.php中,即:
public function validateCredentials(Authenticatable as UserContract $user, array $credentials)
{
dd($user); ==> App\Model\User对象,且$user是$credentials对应的用户
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
当我点UserContract发现它也是一个接口,再搜索
问题
在这个过程中,我十分不理解的是:UserContract是在哪里实例化的,实例化的具体文件是哪个文件?
需求
因为业务需要,我希望为UserProvider加一个redis缓存 ,以解决用户频繁获取token导致的频繁查数据库行为
因为前面跟的这个问题,我发现不仅要重写UserProvider,还要重写UserContract,
但是这两个我都不会...
哪位大神可否指点一二,或提供一下相应解决方案的文档教程,感激!
关于 LearnKu
自定义 UserProvider 即可,参考 https://learnku.com/docs/laravel/5.5/authenticatio...
@leo 我发现它这个UserProvider中的有个核心的验证方法,而这个验证方法才是从数据库生成数据的,应该要同时自定义这个方法才行,也即是下面代码中的UserContract对应Illuminate\Contracts\Auth\Authenticatable,
上层调用这个函数的的时候,传的$user是null,在这个函数里,注入就进来的user就已经是目标对象了,真不知道怎么写...
@vector 来自于同一个类的
retrieveById方法而你要做的实际上也应该是继承
EloquentUserProvider类,但重写retrieveById方法,把由数据库读取改为 缓存+数据库 读取,别的方法不需要重写@leo 好的,我试试,非常感谢:clap: :clap: :clap:
@leo 我在api/vendor/illuminate/auth/EloquentUserProvider.php文件中 的
public function retrieveById($identifier)函数及 public function retrieveByToken($identifier, $token)函数里面加入dd()代码,
但是发现两个函数都没有执行,
而我在public function validateCredentials(UserContract $user, array $credentials)函数里面加入dd是执行的,
且$user已被实例化正确
@vector 说错了,是
retrieveByCredentials这个方法@leo 非常感谢,我试试
@leo 看起来事情没还比较复杂,当我重载EloquentUserProvider后,程序会执行到这个函数,但是当我打印$query->first()时发现是空值。于是我尝试直接返回null,结果它响应到正确的结果了,由此看来还不止这个函数 需要重载…所以,到目前为止,我仍然不知道是哪个文件的哪个函数生成的User实例……
经过进一步测试,我发现$query->first()在一段时间后会返回非空,并且必须返回非空,仍然没有搞明白是怎么回事情
测试到现在 ,我 dd($query->$first()) 一直是NULL,没有任何变化
于是我尝试直接 return null, 结果是一段时间是可以的,但一段里时间不行
只能返回$query->first()才可以,但打印$query->first()一直都是null啊?
是我操作的错误,var_dump($query->first())有值
这玩意极其不稳定……
var_dump($query->first()) 也 NULL了……