1.什么是JWT

JWT(JSON Web Token)是一个开放的行业标准,它定义了一种简介的,自包含的协议格式,用于在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任。JWT可以使用HMAC算法或者使用RSA的公钥/私钥对来进行签名,防止被篡改。

官网: https://jwt.io/

JWT令牌的优点:

  • jwt基于json,非常方便进行解析
  • 可以在令牌中自定义丰富的内容,更容易进行扩展
  • 通过非对称加密算法和数字签名技术,JWT防止篡改,安全性高

JWT令牌的缺点:

  • JWT令牌较长,所占的存储空间比较大。

2.JWT的组成

一个JWT实际就是一个字符串,它由三部分组成:头部,载荷,签名

2.1JWT的头部(Header)

头部用于描述关于该JWT的最基本信息,例如其类型(即JWT)以及签名所用的算法(HMAC,SHA256,RSA)等等

{"alg":"HS256","typ":"JWT"
}
  • alg:表示签名使用的算法
  • typ:类型

我们对头部的json字符串进行BASE64编码后就能得到一个字符串,JDK中提供了非常方便的BASE64EncoderBASE64Decoder,用它们可以非常方便的完成基于BASE64的编码和解码。

2.2载荷(Payload)

第二部分的内容是载荷,就是存放有效信息的地方,这些有效信息包含三个部分

  1. 标准中注册的声明(建议但不强制使用)

    iss: jwt的签发者
    sub: jwt所面向的用户
    aud: 接收jwt的一方
    exp: jwt的过期时间,这个过期时间必须大于签发时间
    iat: jwt的签发时间
    nbf: 定义在什么时间之前,这个jwt都是不可用的
    jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
    
  2. 公共的声明

    ​ 公共的声明可以添加任何的信息,一般添加用户的相关信息或者其他业务需要的必要信息, 但不建议添加敏感的信息,因为载荷可以解密。

  3. 私有的声明

    ​ 私有声明是提供者和消费者所共同定义的声明,一般还是不建议存放敏感的信息,因为base64是对称解密的,意味着这一部分的信息可以归类为明文信息。

自定义claim,比如下面例子中的name就属于自定义的claim。这些claim跟JWT标准规定的claim区别在于:JWT规定的claim在接收方拿到JWT后,都知道怎么对标准的claim进行验证,而私有的claim不会验证,除非明确告诉接收方要对这些claim进行验证以及验证的规则才行。

{"sub":"2390866852","name":"Test","iat":"12312323"
}

上面的name是自定义的声明(公共的或者私有的),而另外两部分是标准的声明

2.3签证,签名(signature)

jwt的第三部分是一个签证的信息,这个签证信息由三部分组成:

  1. header(base64编码后的)
  2. payload(base64编码后的)
  3. secret(盐,一定要保密)

​ 这个部分需要base64加密后的header和payload使用**.**连接组成的字符串,然后通过header中声明的加密模式进行加盐secret组合加密,形成一个完整的签证

将这三个部分用 . 连接拼成一个完整的字符串,也就是最终的jwt

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来对jwt的签发和验证,所以它就是你服务端的私钥,在任何的场景中都不应该泄露出去,一旦客户端得知了你的盐,那就意味着客户端可以进行自我的签发jwt。

3.JJWT快速使用

jjwt是jwt在java中的主流应用,下面将实现一个demo进行学习

新建第一个springboot的项目进行测试

pom.xml

        <!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>

3.1创建token

    /*** 创建token*/@Testpublic void testCreateToken() {//创建JwtBuilder对象JwtBuilder jwtBuilder = Jwts.builder()//声明的唯一标识{"jti":"6666"}.setId("6666")//主体,面向的用户{"sub":"Test"}.setSubject("Test")//签发时间{"iat":"xxxxx"}.setIssuedAt(new Date())//签证.signWith(SignatureAlgorithm.HS256, "scret");//获取jwt的tokenString token = jwtBuilder.compact();System.out.println(token);System.out.println("======================");String[] split = token.split("\\.");//头部System.out.println(Base64Codec.BASE64.decodeToString(split[0]));//载荷System.out.println(Base64Codec.BASE64.decodeToString(split[1]));//盐,无法解析System.out.println(Base64Codec.BASE64.decodeToString(split[2]));}

3.2解析token

    /*** 解析token*/@Testpublic void testParesToken() {String token = "eyJhbGciOiJIUzI1NiJ9." +"eyJqdGkiOiI2NjY2Iiwic3ViIjoiVGVzdCIsImlhdCI6MTY2MzIxMTA3Mn0." +"BcbZ2T_kmFg94-L3z1TXCCEDln1qwX-F9cPs9WiK8Fc";//解析token获取负载中声明的对象Claims claims = Jwts.parser().setSigningKey("scret").parseClaimsJws(token).getBody();System.out.println("id:" + claims.getId());System.out.println("sub:" + claims.getSubject());System.out.println("issuedAt:" + claims.getIssuedAt());}

运行解析token得到如下结果:

3.3创建有失效时间的token

    /*** 创建token(失效时间)*/@Testpublic void testCreateTokenHasExp() {//当前系统时间long now = System.currentTimeMillis();//失效时间(当前系统时间+1分钟)long exp = now + 60 * 1000;//创建JwtBuilder对象JwtBuilder jwtBuilder = Jwts.builder()//声明的唯一标识{"jti":"6666"}.setId("6666")//主体,面向的用户{"sub":"Test"}.setSubject("Test")//签发时间{"iat":"xxxxx"}.setIssuedAt(new Date())//签证.signWith(SignatureAlgorithm.HS256, "scret")//失效时间{"exp":"xxxxx"}.setExpiration(new Date(exp));//获取jwt的tokenString token = jwtBuilder.compact();System.out.println(token);System.out.println("======================");String[] split = token.split("\\.");//头部System.out.println(Base64Codec.BASE64.decodeToString(split[0]));//载荷System.out.println(Base64Codec.BASE64.decodeToString(split[1]));//盐,无法解析System.out.println(Base64Codec.BASE64.decodeToString(split[2]));}

3.4解析有失效时间的token

    /*** 解析token(失效时间)*/@Testpublic void testParesTokenHasExp() {String token = "eyJhbGciOiJIUzI1NiJ9." +"eyJqdGkiOiI2NjY2Iiwic3ViIjoiVGVzdCIsImlhdCI6MTY2MzIxMjEwMiwiZXhwIjoxNjYzMjEyMTYyfQ." +"PKH59MVUuwmkBWTw7cCN3L3eg_atHaCGwuoe5wNQbJs";//解析token获取负载中声明的对象Claims claims = Jwts.parser().setSigningKey("scret").parseClaimsJws(token).getBody();System.out.println("id:" + claims.getId());System.out.println("sub:" + claims.getSubject());System.out.println("issuedAt:" + claims.getIssuedAt());SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println("签发时间:" + simpleDateFormat.format(claims.getIssuedAt()));System.out.println("过期时间:" + simpleDateFormat.format(claims.getExpiration()));System.out.println("当前时间:" + simpleDateFormat.format(new Date()));}

当设置的token已经失效后,会出现如下错误:

3.5创建自定义token

    /*** 创建token(自定义)*/@Testpublic void testCreateTokenByClaims() {//创建JwtBuilder对象JwtBuilder jwtBuilder = Jwts.builder()//声明的唯一标识{"jti":"6666"}.setId("6666")//主体,面向的用户{"sub":"Test"}.setSubject("Test")//签发时间{"iat":"xxxxx"}.setIssuedAt(new Date())//签证.signWith(SignatureAlgorithm.HS256, "scret")//自定义声明.claim("role", "admin").claim("info", "top");//获取jwt的tokenString token = jwtBuilder.compact();System.out.println(token);System.out.println("======================");String[] split = token.split("\\.");//头部System.out.println(Base64Codec.BASE64.decodeToString(split[0]));//载荷System.out.println(Base64Codec.BASE64.decodeToString(split[1]));//盐,无法解析System.out.println(Base64Codec.BASE64.decodeToString(split[2]));}

3.6解析自定义token

    /*** 解析token(自定义)*/@Testpublic void testParesTokenByClaims() {String token = "eyJhbGciOiJIUzI1NiJ9." +"eyJqdGkiOiI2NjY2Iiwic3ViIjoiVGVzdCIsImlhdCI6MTY2MzIxMjUxNCwicm9sZSI6ImFkbWluIiwiaW5mbyI6InRvcCJ9." +"v69wR_j8HXXto0A5QPl6paQDZaHSrBwZ-QZtTwvi6dw";//解析token获取负载中声明的对象Claims claims = Jwts.parser().setSigningKey("scret").parseClaimsJws(token).getBody();System.out.println("id:" + claims.getId());System.out.println("sub:" + claims.getSubject());System.out.println("issuedAt:" + claims.getIssuedAt());System.out.println("role:" + claims.get("role"));System.out.println("info:" + claims.get("info"));}

解析自定义token信息出现如下结果:

以上就是在java中对jwt的简单使用,完整源代码在gitee仓库!

JWT的学习和JJWT的使用相关推荐

  1. JWT的讲解以及JJWT的使用(另附JWT工具类)

    0. 前言 关于JWT的文章网上已经多如牛毛了,但是相信很多同学学的还是云里雾里,所以在我学习JWT之后尽量用最简洁的描述写下这篇文章用于日后复习,与此同时也希望可以帮助同学们共同进步,如果文章对你有 ...

  2. 常用工具类之jwt的学习使用

    什么是jwt 首先jwt其实是三个英语单词JSON Web Token的缩写.通过全名你可能就有一个基本的认知了.token一般都是用来认证的,比如我们系统中常用的用户登录token可以用来认证该用户 ...

  3. JWT详解、JJWT使用、token 令牌

    前言 在正式讲解JWT之前,我们先重温一下用户身份认证相关的一些概念: 有状态登录(session认证) 服务器当中记录每一次的登录信息,从而根据客户端发送的数据来判断登录过来的用户是否合法. 缺点: ...

  4. JWT --- 入门学习

    1.常见的认证机制 basic auth : 每次请求都会携带用户的username,password,易被黑客拦截. Cookie auth : 我们请求服务器,创建一个session对象,客户端创 ...

  5. token学习笔记(JWT、jjwt的使用及案例实现)

    文章目录 1. 首先.了解什么是会话 2. 会话跟踪的主要技术 3. Token 令牌学习 3.1 流程图 3.2 token 3.3 JWT(JSON web Tokens)Json web 令牌( ...

  6. JWT 和 JJWT,别再傻傻分不清了!

    来源 | https://blog.csdn.net/change_on/article/details/76279441 jwt是什么? JWTs是JSON对象的编码表示.JSON对象由零或多个名称 ...

  7. 还在直接用 JWT 做鉴权?JJWT 真香

    点击关注公众号,回复"1024"获取2TB学习资源! jwt是什么? JWTs是JSON对象的编码表示.JSON对象由零或多个名称/值对组成,其中名称为字符串,值为任意JSON值. ...

  8. 还在直接用JWT做鉴权?JJWT真香

    欢迎关注方志朋的博客,回复"666"获面试宝典 jwt是什么? JWTs是JSON对象的编码表示.JSON对象由零或多个名称/值对组成,其中名称为字符串,值为任意JSON值.JWT ...

  9. JWT 进阶 -- JJWT

    ###jwt是什么? JWTs是JSON对象的编码表示.JSON对象由零或多个名称/值对组成,其中名称为字符串,值为任意JSON值.JWT有助于在clear(例如在URL中)发送这样的信息,可以被信任 ...

最新文章

  1. 机器学习奠基人Michael Jordan:下代技术是融合经济学,解读2项重要进展
  2. BGP边界网关协议线路优势
  3. True Zero Downtime HAProxy Reloads--转载
  4. C++string容器-插入和删除
  5. wordpress列表页调用浏览器,wordpress显示文章浏览量!
  6. centos 静态拨号
  7. 信息学奥赛一本通 1026:空格分隔输出 | OpenJudge NOI 1.1 06
  8. 韦诺之战wesnoth没有声音
  9. 生活随笔: 毕业之前和毕业之后
  10. 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。
  11. 拓扑排序以及拓扑排序算法
  12. 计算机桌面背景不见,电脑桌面背景不见了
  13. ATF(Arm Trusted Firmware)/TF-A Chapter 03 Chain of Trust (CoT)
  14. vue项目,地址栏中含有#是什么意思?如何去掉?
  15. Docker 学习笔记(Docker 架构 / 镜像 / 容器 / 常用命令 / Dockerfile / 镜像仓库)
  16. JS实现RGB,HSL,HSB相互转换
  17. 粒子滤波跟踪算法及实现
  18. (三)计算机视觉 --SIFT特征匹配、地理标记图像匹配及RANSAC图像拼接
  19. 背景图片与图片对盒子的影响
  20. mysql 文本挖掘_GitHub - HuiHuiT/dianping_textmining: 大众点评评论文本挖掘,包括点评数据爬取、数据清洗入库、数据分析、评论情感分析等的完整挖掘项目...

热门文章

  1. 【自己写全景】TreeJs实现全景图
  2. 【问题记录】04 MyBatis报错:Parameter ‘XXX‘ not found. Available parameters are [page, hashMap, param1, param
  3. 百度移动优化:关于移动端点击图片放大有多少人注意?
  4. 结构建模设计——Solidworks软件之草图几何关系绘制与草图编辑功能总结(裁剪实体、转换实体引用、等距实体)
  5. 项目建设方案的基本元素
  6. 上午还在改bug,下午就被离职!年底大裁员寒潮来袭……
  7. 【C++/数据结构】先序遍历+中序遍历构建二叉树
  8. ST公司三轴加速度计LIS3DH应用
  9. 怎么预防远程控制计算机,电脑被远程控制怎么办_怎么禁止别人远程控制计算机...
  10. 华硕z170a如何开启m2_华硕Z170主板bios如何设置|华硕Z170主板设置bios的方法