大家好,我是不才陈某~

今天这篇文章介绍一下如何在修改密码修改权限注销等场景下使JWT失效。

文章的目录如下:

解决方案

JWT最大的一个优势在于它是无状态的,自身包含了认证鉴权所需要的所有信息,服务器端无需对其存储,从而给服务器减少了存储开销。

但是无状态引出的问题也是可想而知的,它无法作废未过期的JWT。举例说明注销场景下,就传统的cookie/session认证机制,只需要把存在服务器端的session删掉就OK了。

但是JWT呢,它是不存在服务器端的啊,好的那我删存在客户端的JWT行了吧。额,社会本就复杂别再欺骗自己了好么,被你在客户端删掉的JWT还是可以通过服务器端认证的。

使用JWT要非常明确的一点:JWT失效的唯一途径就是等待时间过期

但是可以借助外力保存JWT的状态,这时就有人问了:你这不是打脸吗?用JWT就因为它的无状态性,这时候又要保存它的状态?

其实不然,这不被逼上梁山了吗?不使用外力保存JWT的状态,你说如何实现注销失效?

常用的方案有两种,白名单黑名单方式。

1、白名单

白名单的逻辑很简单:认证通过时,将JWT存入redis中,注销时,将JWT从redis中移出。这种方式和cookie/session的方式大同小异。

2、黑名单

黑名单的逻辑也非常简单:注销时,将JWT放入redis中,并且设置过期时间为JWT的过期时间;请求资源时判断该JWT是否在redis中,如果存在则拒绝访问。

白名单和黑名单这两种方案都比较好实现,但是黑名单带给服务器的压力远远小于白名单,毕竟注销不是经常性操作。

黑名单方式实现

下面以黑名单的方式介绍一下如何在网关层面实现JWT的注销失效。

究竟向Redis中存储什么?

如果直接存储JWT令牌可行吗?当然可行,不过JWT令牌可是很长的哦,这样对内存的要求也是挺高的。

熟悉JWT令牌的都知道,JWT令牌中有一个jti字段,这个字段可以说是JWT令牌的唯一ID了,如下:

因此可以将这个jti字段存入redis中,作为唯一令牌标识,这样一来是不是节省了很多的内存?

如何实现呢? 分为两步:

  1. 网关层的全局过滤器中需要判断黑名单是否存在当前JWT
  2. 注销接口中将JWT的jti字段作为key存放到redis中,且设置了JWT的过期时间

1、网关层解析JWT的jti、过期时间放入请求头中

在网关的全局过滤器GlobalAuthenticationFilter中直接从令牌中解析出jti过期时间

这里的逻辑分为如下步骤:

  1. 解析JWT令牌的jti和过期时间
  2. 根据jti从redis中查询是否存在黑名单中,如果存在则直接拦截,否则放行
  3. 将解析的jti和过期时间封装到JSON中,传递给下游微服务

关键代码如下:

2、下游微服务的过滤器修改

还记得上篇文章:实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!中微服务的过滤器AuthenticationFilter吗?

AuthenticationFilter这个过滤器用来解密网关层传递的JSON数据,并将其封装到Request中,这样在业务方法中便可以随时获取到想要的用户信息。

这里我是把JWT相关的信息同时封装到了Request中,实体类为JwtInformation,如下:

LoginVal继承了JwtInformation,如下:

此时AuthenticationFilter这个过滤器修改起来就很简单了,只需要将jti和过期时间封装到LoginVal中即可,关键代码如下:

逻辑很简单,上图都有标注。

3、注销接口实现

之前文章中并没有提供注销接口,因为无状态的JWT根本不需要退出登录,傻等着过期呗。

当然为了实现注销登录,借助了Redis,那么注销接口必不可少了。

逻辑很简单,直接将退出登录的JWT令牌的jti设置到Redis中,过期时间设置为JWT过期时间即可。代码如下:

OK了,至此已经实现了JWT注销登录的功能.......

涉及到的三个模块的改动,分别如下:

名称 功能
oauth2-cloud-auth-server OAuth2.0认证授权服
oauth2-cloud-gateway 网关服务
oauth2-cloud-auth-common 公共模块

总结

思想很简单,JWT既然是无状态的,只能借助Redis记录它的状态,这样才能达到使其失效的目的。

测试

业务基本完成了,下面走一个流程测试一下,如下:

1、登录,申请令牌

2、拿着令牌访问接口

该令牌并没有注销,因此可以正常访问,如下:

3、调用接口注销登录

请求如下:

4、拿着注销的令牌访问接口

由于令牌已经注销了,因此肯定访问不通接口,返回如下:

实战!退出登录时如何借助外力使JWT令牌失效?的更多相关文章

  1. iOS 创建一个在退出登录时可以销毁的单例

    一.单例简介 单例模式是在软件开发中经常用的一种模式.单例模式通俗的理解是,在整个软件生命周期内,一个类只能有一个实例对象存在. 二.遇到的问题 在平时开发使用单例的过程中,有时候会有这样的需求,在用 ...

  2. Spring Cloud实战 | 最终篇:Spring Cloud Gateway+Spring Security OAuth2集成统一认证授权平台下实现注销使JWT失效方案

    一. 前言 在上一篇文章介绍 youlai-mall 项目中,通过整合Spring Cloud Gateway.Spring Security OAuth2.JWT等技术实现了微服务下统一认证授权平台 ...

  3. Application作用域实现:当用户重复登录时,挤掉原来的用户

    Application作用域实现:当用户重复登录时,挤掉原来的用户 一.实现思想 1.application(ServletContext)是保存在服务器端的作用域,我们在application中保存 ...

  4. 【招聘App】—— React/Nodejs/MongoDB全栈项目:个人中心&退出登录

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...

  5. 清除@SessionAttributes 网站实现退出登录

    在网站实现登录时,我认识了@SessionAttributes,对我来说是真的好用,@SessionAttributes注解可以使得模型中的数据存储一份到session域中. 这样在页面跳转时可以直接 ...

  6. Spring Security 实战干货:实现自定义退出登录

    文章目录 1. 前言 2. 我们使用 Spring Security 登录后都做了什么 2. 退出登录需要我们做什么 3. Spring Security 中的退出登录 3.1 LogoutFilte ...

  7. 模拟淘宝登录和购物车功能:使用cookie记录登录名,下次登录时能够记得上次的登录名,使用cookie模拟购物车功能,使用session记住登录信息并验证是否登录,防止利用url打开网站,并实现退出登录功能

    Login <%@ page language="java" contentType="text/html; charset=UTF-8" pageEnc ...

  8. odoo8登录时,同帐号在其它客户端的连接自动退出

    odoo跟大多数B/S系统一样,同一个帐号可以在不同的电脑上登录,并且可以同时操作,这样子会带来一些权限上的漏洞.为了解决这个问题,经过分析odoo的session处理机制,开发了一个模块,安装此模块 ...

  9. 34、Django实战第34天:退出登录

    编辑users.view.spy ... from django.contrib.auth import authenticate, login, logout from django.http im ...

随机推荐

  1. 如何使用 Kind 快速创建 K8s 集群?

    作者|段超 来源|尔达 Erda 公众号 ​ 导读:Erda 作为一站式云原生 PaaS 平台,现已面向广大开发者完成 70w+ 核心代码全部开源!在 Erda 开源的同时,我们计划编写<基于 ...

  2. windows Visual Studio 上安装 CUDA【转载】

    原文 : http://blog.csdn.net/augusdi/article/details/12527497  前提安装: Visual Studio 2012 Visual Assist X ...

  3. Oracle参数文件—pfile与spfile

    oracle的参数文件:pfile和spfile 1.pfile和spfile       Oracle中的参数文件是一个包含一系列参数以及参数对应值的操作系统文件.它们是在数据库实例启动时候加载的, ...

  4. Linux基础命令---ntpdate网络时间服务器

    ntpdate ntpdate指令通过轮询指定为服务器参数的网络时间协议(NTP)服务器来设置本地日期和时间,从而确定正确的时间. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS ...

  5. SpringBoot java配置类@Configuration 的两种写法

    首先在Springboot项目中,件一个java类,使用注解@Configuration  ,则这个类是SpringBoot bean的创建的配置文件类,,这种配置文件类有两种写法 1.使用包扫描 , ...

  6. Linux 双网卡绑定及Bridge

    Linux 双网卡绑定及Bridge 阅读(5,202) 一:linux操作系统下双网卡绑定有七种模式.现在一般的企业都会使用双网卡接入,这样既能添加网络带宽,同时又能做相应的冗余,可以说是好处多多. ...

  7. matplotlib画直线图的基本用法

    一  figure使用 1 import numpy as np 2 import matplotlib.pyplot as plt 3 4 # 从-3到中取50个数 5 x = np.linspac ...

  8. SSM框架整合后使用pagehelper实现分页功能

    一.导入pagehelper-5.1.10.jar和jsqlparser-3.1.jar两个jar包 二.配置pagehelper 2.1 在mybatis配置文件中配置 <plugins> ...

  9. Java实现HttpGet和HttpPost请求

    maven引入JSON处理jar <dependency> <groupId>com.alibaba</groupId> <artifactId>fas ...

  10. Table.RemoveLastN删除后面N….RemoveLastN(Power Query 之 M 语言)

    数据源: "姓名""基数""个人比例""个人缴纳""公司比例""公司缴纳"&qu ...