本来使用 Token 就是为了去中心化,服务无状态,但是有时候好处也会变为坏处,意味着一但 Token 发布出去了,我们就失去了控制权,但有时候我们又希望我们还能主动控制 Token 失效。比方说在用户退出登录,或者 Token 的 Payload 数据变更需要将旧的 Token 失效掉,促使用户使用新的 Token。
每次用户登录认证成功后,将 Token 的唯一 ID 保存到 Redis,当需要将 Token 主动失效的时候,将 Redis 缓存的 Token 对应 ID 删除,那么用户再次拿着失效 Token 来请求的话,判断服务端是否有缓存该 Token 对应的 ID,如果没有的话则拒绝服务,提示用户重新登录认证获取新的 Token。
这种黑名单机制与白名单机制思想类似差不多,依然是借助一个第三方来保存 Token 的状态,但是相较于白名单机制做了一些改进,它不是在用户登录认证成功就缓存用户的 Token,而是在需要主动触发某个 Token 失效的情况下,将这个失效的 Token 缓存到 Redis 这种第三方缓存中间件,然后当用户带着已失效的 Token 来访问时,去缓存中判断是否有该 Token 存在,如果有的话拒绝服务。但是就笔者看来,这种方案可能会存在一个问题,就是当某些恶意用户一直重复触发 Token 失效(比方说退出登录操作)那么你的缓存可能会有很多失效的 Token,最终造成内存溢出。
秘钥刷新机制是为每个用户提供专属的生成 Token 的秘钥 Key,然后当触发 Token 时候失效的时候,修改重置用户的秘钥 Key,那么秘钥 Key变更了,在解密鉴权的时候之前的 Token 都会因为秘钥对不上解密失败,从而达到 Token 失效的目的。那么修改重置后的秘钥 Key 如何同步给其它的网关或者 Token 鉴权服务了,第一种方案就是将用户的秘钥 Key 保存到 Redis 缓存中,每次去读取最新的秘钥 Key。第二种方案则是使用消息中间件通知网关服务更新用户的秘钥 Key,使用这种方案就不需要每次请求都要去增加的额外网络请求去读取秘钥 Key,但是同时带来的问题就是可能存在数据滞后的问题,当你拿着最新秘钥生成的 Token 去请求到一台还未更新到最新秘钥的网关服务,则可能会出现认证失败的问题,这种情况可能需要适当的增加重试机制来完善。
工具 — Mar 17, 2023