记一次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服务容器和服务提供者强大的地方。

猜你喜欢

转载自www.cnblogs.com/SHQHDMR/p/10229001.html
今日推荐