目录

1.什么是JWT

2.JWT什么时候去使用,有什么好处

3 JWT问题和趋势

4 JWT的组成

头部

有效载荷

签名

4.java中使用


1.什么是JWT

JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSAECDSA的公钥/私钥对对JWT进行签名

尽管可以对JWT进行加密以在双方之间提供保密性,但我们将重点关注已签名的令牌。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌则将这些声明隐藏在其他方的面前。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。

2.JWT什么时候去使用,有什么好处

授权: 这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用

信息交换: JSONWeb令牌是在各方之间安全地传输信息的好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确定发件人是他们所说的人。另外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。

支持跨域访问:Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输.

无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.

去耦:不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可.(这个似乎也在继续说前面第一点和第二点的好处。。。)

更适用于移动应用:当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。

CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。(如果token是用cookie保存,CSRF还是需要考虑,一般建议使用1、在HTTP请求中以参数的形式加入一个服务器端产生的token。或者2.放入http请求头中也就是一次性给所有该类请求加上csrftoken这个HTTP头属性,并把token值放入其中)

基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft)

性能:JWT不仅可用于认证,还可用于信息交换。善用JWT有助于减少服务器请求数据库的次数,请求数据库的一次网络往返时间(通过数据库查询session信息),相对比HMAC SHA256计算Token验证和解析要费时得多。

3 JWT问题和趋势

令牌问题:JWT默认不加密,但可以加密。生成原始令牌后,可以使用该令牌再次对其进行加密。

会话状态:JWT的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦JWT签发,在有效期内将会一直有效。

安全问题:JWT本身包含认证信息,因此一旦信息泄露,任何人都可以获得令牌的所有权限。为了减少盗用,JWT的有效期不宜设置太长。对于某些重要操作,用户在使用时应该每次都进行进行身份验证。而且JWT不建议使用HTTP协议来传输代码,为了减少盗用和窃取,而是使用加密的HTTPS协议进行传输。

4 JWT的组成

JSON Web令牌以紧凑的形式由三部分组成,这些部分由点(.)分隔,分别是:

  • 头部
  • 有效载荷
  • 签名

因此,JWT通常如下结构所示。

xxxxx.yyyyy.zzzzz

头部

JWT头部分是一个描述JWT元数据的JSON对象,通常如下所示。

{"alg": "HS256","typ": "JWT"
}

alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。

最后,使用Base64 URL算法将上述JSON对象转换为字符串保存,。

然后,此JSON被Base64 Url编码以形成JWT的第一部分。

有效载荷

有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择

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

除以上默认字段外,我们还可以自定义私有字段,如下例:

{"sub": "1234567890","name": "John Doe","admin": true
}

然后,对有效负载进行Base64Url编码,以形成JSON Web令牌的第二部分。

注意:

JWT头和有效载荷序列化的算法都用到了Base64 URL,该算法和常见Base64算法类似,稍有差别。

对于已签名的令牌,此信息尽管可以防止篡改,但任何人都可以读取。除非将其加密,否则请勿将重要信息放入JWT的有效负载或报头元素中。

签名

签名部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。

我们需要指定一个密钥(secret)。该密码仅在服务器中使用,不能公开。然后,使用标头中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名

HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

注意:

签名主要通过密钥进行加密解密,用于验证JWT在整个过程中有没有被更改,保证JWT的完整性。

作为令牌的JWT可以放在URL中(例如api.example/?token=xxx)。 Base64中用的三个字符是"+","/"和"=",由于在URL中有特殊含义,因此Base64URL中对他们做了替换:"="去掉,"+"用"-"替换,"/"用"_"替换,在使用的时候需要注意。

将这三部分用.连接成一个完整的字符串,构成了最终的jwt:

JWT解析地址:https://jwt.io/#libraries

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

通过解析上面JWT,可以得到以下图中标头,载荷信息:

4.java中使用

在项目中建议使用JJWT,因为其API相对友好

引入Maven依赖

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version>
</dependency>

在项目中新建JwtDemo类

在jwtDemo类中添加以下jwt常量

public class JwtDemo {//加密算法private final static SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;//私钥 / 生成签名的时候使用的秘钥secret,一般可以从本地配置文件中读取,切记这个秘钥不能外露,只在服务端使用,在任何场景都不应该流露出去。// 一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。private final static String secret = "secretKey";// 过期时间(单位秒)/ 2小时private final static Long access_token_expiration = 7200L;//jwt签发者private final static String jwt_iss = "spzhang";//jwt所有人private final static String subject = "zhangsp";}

JWT生成方法

在jwtDemo类下添加以下jwt生成方法

 /*** 创建jwt* @return*      返回生成的jwt token*/public static String generateJwtToken(){// 头部 map / Jwt的头部承载,第一部分// 可不设置 默认格式是{"alg":"HS256"}Map<String, Object> map = new HashMap<>();map.put("alg", "HS256");map.put("typ", "JWT");//载荷 map / Jwt的载荷,第二部分Map<String,Object> claims = new HashMap<String,Object>();//私有声明 / 自定义数据,根据业务需要添加claims.put("id","123456");claims.put("userName", "admin");//标准中注册的声明 (建议但不强制使用)//一旦写标准声明赋值之后,就会覆盖了那些标准的声明claims.put("iss", jwt_iss);/*    iss: jwt签发者sub: jwt所面向的用户aud: 接收jwt的一方exp: jwt的过期时间,这个过期时间必须要大于签发时间nbf: 定义在什么时间之前,该jwt都是不可用的.iat: jwt的签发时间jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击*///下面就是在为payload添加各种标准声明和私有声明了return Jwts.builder() // 这里其实就是new一个JwtBuilder,设置jwt的body.setHeader(map)         // 头部信息.setClaims(claims)      // 载荷信息.setId(UUID.randomUUID().toString()) // 设置jti(JWT ID):是JWT的唯一标识,从而回避重放攻击。.setIssuedAt(new Date())       // 设置iat: jwt的签发时间.setExpiration(new Date(System.currentTimeMillis() + access_token_expiration * 1000)) // 设置exp:jwt过期时间.setSubject(subject)    //设置sub:代表这个jwt所面向的用户,所有人.signWith(SIGNATURE_ALGORITHM, secret)//设置签名:通过签名算法和秘钥生成签名.compact(); // 开始压缩为xxxxx.yyyyy.zzzzz 格式的jwt token}

JWT解析方法

在jwtDemo下添加以下解析方法

 /***  从jwt中获取 载荷 信息* @param jwt* @return*/private static Claims getClaimsFromJwt(String jwt) {Claims claims = null;try {claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(jwt).getBody();} catch (Exception e) {e.printStackTrace();}return claims;}

测试方法

通过Jwt生成Jwt token,并通过解析jwt获取 载荷 信息

    public static void main(String[] args) {String jwtToken = generateJwtToken();System.out.println("JWT Token "+ jwtToken);System.out.println("=======================================================");Claims claims = getClaimsFromJwt(jwtToken);System.out.println(claims);System.out.println(claims.get("userName"));}

通过执行得到了以下信息,可以看到生成时间,和失效时间,自定义数据等

JWT Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ6aGFuZ3NwIiwiaXNzIjoic3B6aGFuZyIsImlkIjoiMTIzNDU2IiwidXNlck5hbWUiOiJhZG1pbiIsImV4cCI6MTU3NjEyODQzMSwiaWF0IjoxNTc2MTIxMjMxLCJqdGkiOiI1YWM1NTYyMy03MGMyLTRkYzgtYThkMC1lMGFlY2I5OTNmMTQifQ.51y0YnmPvDJBzzMe9aNwkZG6Pgcvqq6vJHtaTuY1CEI
=======================================================
{sub=zhangsp, iss=spzhang, id=123456, userName=admin, exp=1576128431, iat=1576121231, jti=5ac55623-70c2-4dc8-a8d0-e0aecb993f14}
admin


Java中详细使用JWT(JJWT)相关推荐

  1. JWT|概述|JWT结构|JWT在java中的使用|JWT工具类的封装|JWT在springboot中的使用|JWT与拦截器的配合

    JWT ! 前记: 官网:https://jwt.io/ jwt有人说是用计算力换空间(相对于session) 小程序后台要求全部用springboot实现..登录状态的管理:本来想用自己随便生成UU ...

  2. 了解Java中的内存泄漏

    来源:SpringForAll社区 1. 简介 Java的核心优势之一是在内置垃圾收集器(简称GC)的帮助下实现自动内存管理.GC隐含地负责分配和释放内存,因此能够处理大多数内存泄漏问题. 虽然GC有 ...

  3. Java Token登录验证 使用jjwt生成和解析JWT

    Java jjwt生成和解析Token 参考 依赖 流程 生成和解析Jwt 生成jwt 解析Jwt 实例 后端 前端 刚学会了点使用Jwt来验证登录,记录下来 参考 JSON Web Tokens官网 ...

  4. java中的token机制,基于JWT的Token认证机制java实现(二)

    Java的JJWT实现JWT. JJWT是一个提供端到端的JWT创建和验证的Java库.永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解.它被设计成一个以建筑为中心 ...

  5. Java中的多线程编程(超详细总结)

    文章目录 Java中的多线程编程(超详细总结) 一.线程与多线程的概念 二.线程与进程之间的关系 三.一个线程的生命周期 四.多线程的目的和意义 五.线程的实现的方式 Java中的多线程编程(超详细总 ...

  6. c枚举类型enum例题_一篇文章让你详细了解Java中Enum枚举类的使用

    文章前记 程序员工作久了便可能整日忙碌于"增删改查"中,迷失方向,毫无进步. 该公众号致力于分享软件开发相关的原创干货,助你完成从程序员到架构师的进阶之路! 努力!做一个NB的Co ...

  7. java中char占的二进制,java数据类型与二进制详细介绍

    java数据类型与二进制详细介绍 在java中 Int 类型的变量占 4个字节 Long 类型的变量占8个字节 一个程序就是一个世界,变量是这个程序的基本单位. Java基本数据类型 1. 整数类型 ...

  8. 一看你就懂,超详细java中的ClassLoader详解

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于某些框架开发者来说却非常常见.理解ClassL ...

  9. 【视频】详解Scala中的类及与Java的详细区别

    详解Scala中的类及与Java的详细区别

  10. 第八节:详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架

    前言 大家好,给大家带来详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架的概述,希望你们喜欢 JAVA 异常 try...catch...finally结构的使用方法 class Tes ...

最新文章

  1. 【嵌入式开发】时钟初始化 ( 时钟相关概念 | 嵌入式时钟体系 | Lock Time | 分频参数设置 | CPU 异步模式设置 | APLL MPLL 时钟频率设置 )
  2. 基于迭代次数和分类准确率的两种排序
  3. 文件操作中file.seek()方法
  4. 【实战】MPLS单域通信过程详解
  5. 【软考-软件设计师】计算机体系结构的分类
  6. K-均值聚类算法对未标注数据分组(1)
  7. 使用Bootstrap开发网站首页
  8. 【51单片机快速入门指南】6.1:LCD1602的八线、四线控制及自定义符号,完美兼容Proteus仿真
  9. python pandas dataframe 排序,如何按两列或更多列对python pandas中的dataFrame进行排序?...
  10. 飞鸽传书(http://www.freeeim.com)软件下载
  11. kolla all-in-one 安装
  12. 2021年中国再生纱市场趋势报告、技术动态创新及2027年市场预测
  13. 网站直达上线运营,API接口开发中
  14. APP中一种在Java层实现的简单守护进程方式
  15. [R语言统计]频数表
  16. vmware虚拟机共享文件夹设置(xp)
  17. 一张程序员人生图,很有意思
  18. Abel逆变换及其求解方法
  19. 爬取百思不得姐段子图片
  20. flex布局对行内子元素的影响

热门文章

  1. Robot Framework自动化测试用具 Wait Until Keyword Succeeds关键字使用案例
  2. Windows系统下的Git安装教程
  3. hihocoder 1224 赛车
  4. iOS 多线程dispatch_async dispatch_sync(GCD)详尽总结
  5. html班级主题完整代码,HTML班级网站
  6. css过渡、动画3D环绕相册
  7. K.dot和K.batch_dot
  8. Vagrant-文件夹共享
  9. 创建型模式 - 单例模式Singleton
  10. 明翰英语教学系列之形容词与副词篇V0.1(持续更新)