# kong-plugin-jwt-blacklist **Repository Path**: xuededong/kong-plugin-jwt-blacklist ## Basic Information - **Project Name**: kong-plugin-jwt-blacklist - **Description**: 扩展Kong官方jwt插件,增加token黑名单验证 - **Primary Language**: Lua - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 5 - **Created**: 2020-05-18 - **Last Updated**: 2022-11-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Kong Jwt plugin with blacklist 扩展[官方jwt插件](https://docs.konghq.com/hub/kong-inc/jwt/),保留token过期及签名验证,增加根据jti查询redis黑名单数据库,实现强制下线。 ## 项目地址 https://gitee.com/nullpointerxyz/kong-plugin-jwt-blacklist.git ## 扩展功能 - 增加在header中添加自定义`x-userId` - 可配置的在转发到上游服务前,删除header中的jwt - 优化配置参数,删除从cookie获取token,支持从url和header获取token,增加redis配置,增加默认值。 - 验证payload是否含有jti,没有返回401。 - 验证jti是否在黑名单,若在返回401和对应的value。 ## 使用 #### 1. 增加一个service,url为http://mockbin.org/request ![](https://oscimg.oschina.net/oscnet/up-966aec8b7413ce57d884a4970746c9ffc72.png) #### 2. 增加一个router,path为/mock ![](https://oscimg.oschina.net/oscnet/up-161ff2787a9735e247a1cbe48bd44778626.png) #### 3. 增加jwt插件,配置如下 ![](https://oscimg.oschina.net/oscnet/up-4ede6d9056577e971ba45b7e9a7f9084bbf.png) ![](https://oscimg.oschina.net/oscnet/up-7b9850e917a6c1946419d61a1542ea6b68f.png) #### 4. 调用我们的授权服务获取一个access_token ![](https://oscimg.oschina.net/oscnet/up-936c936cde3d44e951133df379855f00cb9.png) #### 5. 添加一个CONSUMER,配置jwt key和公钥 ![](https://oscimg.oschina.net/oscnet/up-92ed7298c621a03eabe4709f524312654cc.png) #### 6. 在redis数据库中增加key为prefix+jti ![](https://oscimg.oschina.net/oscnet/up-00ea909f7bccd37aae785effa4795e58509.png) #### 7. 携带token访问service,验证结果 ![](https://oscimg.oschina.net/oscnet/up-ad4d2e30d0caf0673fa9d2930abf9a251e7.png) ## 核心代码 ``` { redis_host = { type = "string", required = true, default = "127.0.0.1" } }, { redis_port = { type = "number", required = true, default = 6379 } }, { redis_db = { type = "number", required = true, default = 0 } }, { redis_password = { type = "string", } }, { string_key_prefix = { type = "string", required = true, default = "userOffline:" } }, ``` ``` function checkJti(conf, jti) if not jti then return false, { status = 401, message = "Invalid jti in claims" } end local red = redis:new() red:set_timeout(1000) local ok, err = red:connect(conf.redis_host, conf.redis_port) if not ok then kong.log.err("failed to connect : ", err) return end if conf.redis_password and conf.redis_password ~= "" then local count count, err = red:get_reused_times() if 0 == count then ok, err = red:auth(conf.redis_password) if not ok then kong.log.err("failed to auth: ", err) return end elseif err then kong.log.err("failed to get reused times: ", err) return end end ok, err = red:select(conf.redis_db) if not ok then kong.log.err("failed to select db: ", err) return end -- get key local res, err = red:get(conf.string_key_prefix .. jti) kong.log.notice("red:get:", conf.string_key_prefix .. jti, ",value=", res) if err then kong.log.err("failed to get key", conf.string_key_prefix .. jti) end --连接池大小是100个,并且设置最大的空闲时间是 10 秒 ok, err = red:set_keepalive(10000, 100) if not ok then kong.log.err("failed to set keepalive: ", err) return end if res ~= ngx.null then return false, { status = 401, message = res } end return true end ``` ​