JSON Web Token (JWT)是一个开放标准,它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。JWT主要有两种使用场景。

  • Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
  • Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWT可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。

JWT和银行存款的票据比较相似,在获取token后,后续服务器和客户端的交互都可以通过这个token完成。JWT分为三部分:Header(头部)、Payload(负载)、Signature(签名)。Header部分包括:alg和typ,alg是算法名称,typ统一都是JWT。Payload包括签发人、主题、过期时间等信息,具体如下所示。Signature是数字签名,防止数据被篡改。

iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

在使用JWT的过程中,需要注意JWT的以下这些特点:

  • JWT默认是不加密,但也是可以加密的,生成原始Token以后,可以用密钥再加密一次
  • JWT不加密的情况下,不能将敏感数据写入JWT。
  • JWT可以用于认证,也可以用于交换信息。有效使用JWT可以降低服务器查询数据库的次数。
  • JWT的最大缺点是,由于服务器不保存session状态,因此无法在使用过程中废止某个token,或者更改token的权限。也就是说,一旦JWT签发了,在到期之前就会始终有效。
  • JWT本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT的有效期应该设置得比较短
  • 对于一些比较重要的权限,使用时应该再次对用户进行认证,为了减少盗用,JWT不应该使用HTTP协议明码传输,要使用HTTPS协议传输

上面介绍了JWT的一些概念信息,下面就通过实际例子来演示JWT的使用,Demo地址。Demo里面包含了jwt认证授权服务器和资源服务器两部分,资源服务器的代码和之前的例子相同,只是多了在application.properties中设置jwt签名的key,所以重点看看jwt认证授权服务器即可。内容主要包含两部分,jwt的配置,这个基本都是固定配置,具体内容如下所示:

另外还有授权服务器部分的配置,和前面博客介绍的内容相同。通过这两项配置,生成的token就是jwt了,即包含了自认证的token。

启动jwt服务和资源服务后,因为授权服务配置了password和authorization_code两种授权模式,这里就尝试password模式,可以看到返回的response body中包含token和refresh_token.解析返回的jwt,可以看到有header,payload和signature三部分。从这里也可以看到,自包含令牌即授权服务器颁发的令牌包含关于用户或者客户的元数据和声明(Claims),通过检查签名,期望的颁发着(issuer),期望的接收人aud(audience),或者scope,资源服务器可以在本地校验令牌。通常的实现为签名的JSON Web Token(JWT)。

可以看到如果要支持生成JWT,实际很简单,只需要在授权认证服务器上进行一些jwt的固定配置即可。接下来看看一个完善的前后端分离的项目,如何通过jwt完成认证和授权,Demo地址。Demo启动成功后,可以通过swagger发送请求,先调用regiser接口,这样在数据库中就存入了user信息,存入数据库的用户密码信息已经进行了加密处理。

接着调用登陆认证接口,获取token信息,可以看到,token信息用“.”号区分,将token进行解析,也可以看到token被解析为header,payload,signature三部分。解析出来的user信息也就是jwtUser。

这样带着token访问其他接口,例如获取用户信息接口则能成功,否则会返回401的错误。上面展示了实际的效果,接下来看看代码上是如何实现的。与授权认证相关的有3个核心Class。SecurityConfiguration配置类继承了Spring Security的WebSecurityConfigurerAdapter类,这里设置了哪些请求可以不经过认证,哪些请求必须经过认证。将自定义的JwtAuthorizationFilter过滤器添加到Spring Security机制中。而JwtAuthorizationFilter是用户请求授权过滤器,用于从用户请求中获取token信息,并对其进行验证,同时加载与token相关联的用户身份认证信息,并添加到Spring Security上下文中。JwtConfigurer是固定写法。

上一篇博客中,生产Jwt时借助OAuth2来生成的授权的,这里的Demo代码则是通过JWT的算法来生成token,具体代码如下所示,包括验证token等也都封装在JwtUtil类中。

剩下的一些类如Repository、Entity主要是为了对数据库进行增删改查,因为user信息和user_role等信息是存入数据库的。另外,还有DTO(数据传输对象),Exception(异常类定义),Constant(一些常量定义),UserService和UserRoleService主要是调用Repository的一些方法对数据进行处理,AuthService调用其他类的方法组合了authLogin方法。最后是Configure里面的一些配置,除了配置Swagger外,还配置了springframework.data的审计功能。配置审计功能后,相关的数据库表就会自动添加上createBy,createDate等信息。以下是审计的配置类

定义审计Entity,普通Entity继承AbstractAuditingEntity即可自动进行审计功能。

总结而言,对于JWT的使用,最关键的还是生成Token,使用Token,使用Token就包括验证Token的正确性、存储Token,filter配置等。上面的例子中数据库表中只存放了username/password等信息,token是没有进行存放的,那如果要用redis来存放token应该如何实现呢?上面的demo代码中refresh-token分支上就有相关的实现,接下来看看如何通过redis来刷新token。首先在pom文件中引入redis的依赖,且在application.properties中添加redis相关配置。

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><scope>provided</scope></dependency>

接着配置RedisTemplate,实现JwtRedisCacheService,主要包含getValue和setValue方法。

在AuthService中,当生成jwt后,会先存入redis中,然后再写入安全上下文中。

在JwtAutherizationFilter中判断token的有效性,如果token过期,那么会读取缓存的token进行对比,如果缓存中的token和过期token一致,那么会刷新token,并把刷新的token写入redis以及写入接口的responseHeader中。

需要注意一点:这里刷新的token是直接调用JwtUtil重新生成的token,并不是借助refresh_token来获取新的token。

可以看到如果要将token等信息存入redis中并不难,主要是调用set,get方法即可。以上就是对JWT使用的基本介绍。

JWT基本概念和使用介绍相关推荐

  1. nginx虚拟主机概念和类型介绍

    nginx虚拟主机配置实战 1,虚拟主机概念和类型介绍 所谓虚拟主机,在web服务里就是一个独立的网站站点,这个站点对应独立的域名(也可能是IP或端口),具有独立的程序及资源目录,可以独立地对外提供服 ...

  2. 什么是mysql的游标_MySQL游标概念是什么 MySQL游标概念与用法介绍

    本篇文章小编给大家分享一下MySQL游标概念与用法介绍,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 1.游标的概念(Cursor) 一条sql,对应N条资源,取出资源的接 ...

  3. REST API 概念的简单介绍

    REST API 概念的简单介绍 最近发现很多人不了解REST是什么,我综合了下网上的文章,摘录了一下. 首先要明确一点:REST(Representational State Transfer,表述 ...

  4. Druid基本概念及架构介绍

    Druid基本概念及架构介绍 学习参考:https://www.apache-druid.cn/ Apache Druid是一个高性能的实时分析型数据库 作者:it_zzy 链接:https://ww ...

  5. Hadoop的概念及架构介绍

    Hadoop的概念及架构介绍 Hadoop是大数据开发所使用的一个核心框架.使用Hadoop可以方便的管理分布式集群,将海量数据分布式的存储在集群中(hdfs),并使用分布式程序来处理这些数据.(Ma ...

  6. 1. Stateflow - 基本概念,界面介绍

    文章目录 1. Stateflow - 基本概念,界面介绍 1.1 基本概念 1.2 界面内容 1.3 模型设置 专题目录 1. Stateflow - 基本概念,界面介绍 1.1 基本概念 Stat ...

  7. XCP概念和基本原理介绍

    XCP概念和基本原理介绍 ASAM接口模型描述了Slave和Master之间发送和接收命令和数据.为了独立于特定的物理传输层,XCP被细分为协议层和传输层. 根据传输层的不同,可分为XCP ON CA ...

  8. hadoop系列(一)概念、组件介绍、安装环境、配置

    hadoop系列(一)概念.组件介绍.安装环境.配置 一.大数据概念 概念 大数据:解决海量数据的采集.存储.分析计算的能力 大数据特点 Volume(大量) Velocity(高速) Variety ...

  9. 隐私计算概念及应用介绍

    隐私计算概念及应用介绍 0,隐私计算背景 政策背景: 2020 年 4 月,<中共中央国务院关于构建更加完善的要素市场化配置体制机制的意见>发布,将数据作为一种新型生产要素,与土地.劳动力 ...

最新文章

  1. phpstorm支持php7吗,PHPStorm支持PHP7类型提示等新语法
  2. 形态学滤波:腐蚀与膨胀(浅谈)
  3. 微信公众平台开发教程第21篇-“可信网址”白名单
  4. Linux基础(10)--管理文件和目录
  5. 不是美工却依然想写出美丽的CSS该肿么办
  6. 使用缓冲流有什么好处_使用档案密集柜有什么好处?不看一看会后悔
  7. 读书笔记-《人为什么活着》
  8. Ubuntu下wxWidgets学生公寓管理编程,sqlite3的用法(mysql数据库),窗体,下面是部分添加和删除功能,其他功能可以联系我。。...
  9. Java中的几种设计模式:创建型模式,结构型模式
  10. Jquery实现可拖动进度条
  11. 变速齿轮Delphi实现
  12. QT 操作 QLabel
  13. 一线外包员工的生活经历
  14. 树莓派到手第一步:上电启动、安装中文字体、虚拟键盘、开启SSH等
  15. 安徽农业大学计算机考研分数线,安徽农业大学2019年考研复试分数线已公布
  16. matlab中如何调用子函数
  17. vxworks下的脚本script创建和使用(相当于windows下的autoexec.bat)
  18. 深度学习--综述前言
  19. Python NLP 入门教程
  20. Windows系统中 Xmanager 6 企业版下载安装激活教程

热门文章

  1. AttributeUsage特性和特性标识符
  2. C语言 数组查找问题汇总
  3. 想发就发の日常朋友圈文案-小众碎片版
  4. Viva Confetti UVA - 1308
  5. POJ 1418 Viva Confetti 题解 《挑战程序设计竞赛》
  6. SpringBoot+微信小程序训练项目
  7. 如何用python的i2c教程_[Python玩转物联网]Micropython I2C实验
  8. CMake Error at CMakeLists.txt:210 (find_package): By not providing “FindCEF.cmake“ in CMAKE_MODULE
  9. JSplumb 中文教程(前端自定义组件,流程图,拓扑图)
  10. JavaScript 二维数组转一维数组