记一次laravel-jwt修改黑名单所用redis数据库

Posted SHQHDMR

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次laravel-jwt修改黑名单所用redis数据库相关的知识,希望对你有一定的参考价值。

场景是这样的,我用tymon/jwt包做鉴权。jwt是自编码token,过期前想要强制失效只能将其加入黑名单中,黑名单一般用缓存存储。

但会有一个问题,若某种意外情况不小心执行了php aritsan cache:clear,那么当前使用的缓存数据库(配置文件中设置,默认config/database.php->redis->default)会被清空,而tymon/jwt包也是用default数据库的,故黑名单的token也会被一并清空。

如何在不改第三方包的前提下修改黑名单使用的redis数据库?这样token就能独占一库,不用和其他缓存数据一起混在当前使用数据库中,即使php aritsan cache:clear也不会受影响

查看源码:

Tymon\\JWTAuth\\Blacklist.php

 点进继续追踪,发现Storage的实现是Tymon\\JWTAuth\\Providers\\Storage\\Illuminate.php的Illuminate类。

Illuminate在构造函数中注入了一个CacheContract,即Illuminate\\Contracts\\Cache\\Repository,这其实就是laravel的Cache缓存类,最后注入的缓存对象使用的就是config/cache/redis中指定的数据库(已经从第三方包追到框架源码了,所以我就不继续追了),我的场景下就是default

如果我们想让这个包不注入默认的Cache对象,而使用我们指定的Cache对象,我们可以用laravel的服务提供者:https://laravel-china.org/docs/laravel/5.6/providers/1360与服务容器进行上下文绑定:https://laravel-china.org/docs/laravel/5.6/container/1359#contextual-binding

在App\\Providers\\AppServiceProvider->register()方法中

对Tymon\\JWTAuth\\Providers\\Storage\\Illuminate注入的Illuminate\\Contracts\\Cache\\Repository进行注册(注册为我们想要的对象):

/**
* Register any application services.
*
* @return void
*/
public function register()
{
    $this->app->when(Illuminate::class) //use Tymon\\JWTAuth\\Providers\\Storage\\Illuminate
    ->needs(Repository::class)  //use Illuminate\\Contracts\\Cache\\Repository
    ->give(function () {
        return app(\'cache\')->store(\'jwt\');
    });
}

即当Illuminate需要注入Repository时,注入function()闭包内返回的对象,在闭包里用store()方法指定缓存使用的缓存存储,也就是我们自定义的jwt存储(config/cache.php):

驱动使用redis,连接的数据库就是config/database.php->redis中我们自定义的jwt数据库

这样,第三方包注入依赖对象的时候,就会使用服务提供者提供的对象进行注入(我的场景里注入的就是专门jwt数据库的Cache对象),这就是laravel服务容器和服务提供者强大的地方。

以上是关于记一次laravel-jwt修改黑名单所用redis数据库的主要内容,如果未能解决你的问题,请参考以下文章

记一次CVE漏洞检测过程

记一次redis踩坑

记一次Redis Cluster 故障,迁移时--

记一次redis主从同步失败

记一次线上Redis缓存击穿

记一次不成功的redis访问