2019独角兽企业重金招聘Python工程师标准>>>

什么是JWT?

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

jwt的组成

  • Header: 标题包含了令牌的元数据,并且在最小包含签名和/或加密算法的类型
  • Claims: Claims包含您想要签署的任何信息
  • JSON Web Signature (JWS): 在header中指定的使用该算法的数字签名和声明

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
Header:
{"alg": "HS256","typ": "JWT"
}
Claims:
{"sub": "1234567890","name": "John Doe","admin": true
}
Signature:
base64UrlEncode(Header) + "." + base64UrlEncode(Claims)

加密生成的token:

有关JWT的详细介绍,请阅读这篇文章:JWT学习(一):什么是JWT?- JSON WEB TOKEN

JJWT

JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界面,隐藏了它的大部分复杂性。

  • JJWT的目标是最容易使用和理解用于在JVM上创建和验证JSON Web令牌(JWTs)的库。
  • JJWT是基于JWT、JWS、JWE、JWK和JWA RFC规范的Java实现。
  • JJWT还添加了一些不属于规范的便利扩展,比如JWT压缩和索赔强制。

JJWT 规范兼容

  • 创建和解析明文压缩JWTs
  • 创建、解析和验证所有标准JWS算法的数字签名压缩JWTs(又称JWSs):
  • HS256:使用SHA-256的HMAC
  • HS384:使用SHA-384的HMAC
  • HS512:使用SHA-512的HMAC
  • RS256:使用SHA-256的RSASSA-PKCS-v1_5
  • RS384:使用SHA-384的RSASSA-PKCS-v1_5
  • RS512:使用SHA-512的RSASSA-PKCS-v1_5
  • PS256:使用SHA-256的RSASSA-PSS和使用SHA-256的MGF1
  • PS384:使用SHA-384的RSASSA-PSS和使用SHA-384的MGF1
  • PS512:使用SHA-512的RSASSA-PSS和使用SHA-512的MGF1
  • ES256:使用P-256和SHA-256的ECDSA
  • ES384:使用P-384和SHA-384的ECDSA
  • ES512:使用P-521和SHA-512的ECDSA

下面我们根据 https://github.com/jwtk/jjwt 上的demo,来介绍下 JJWT 的用法。

jjwt 安装

jjwt 提供了 Maven 和 Gradle 两种构建方式,Maven 配置如下即可使用 JJWT。

1
2
3
4
5
<dependency>     <groupId>io.jsonwebtoken</groupId>     <artifactId>jjwt</artifactId>     <version>0.9.0</version>
</dependency>

Gradle 使用方式如下:

1
dependencies { compile 'io.jsonwebtoken:jjwt:0.9.0' }

注意:JJWT依赖于Jackson 2.x. 如果您已经在您的应用程序中使用了旧版本的 Jackson 请升级相关配置。

示例代码

签发JWT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static String createJWT() {SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;SecretKey secretKey = generalKey();JwtBuilder builder = Jwts.builder().setId(id)                                      // JWT_ID.setAudience("")                                // 接受者.setClaims(null)                                // 自定义属性.setSubject("")                                 // 主题.setIssuer("")                                  // 签发者.setIssuedAt(new Date())                        // 签发时间.setNotBefore(new Date())                       // 失效时间.setExpiration(long)                                // 过期时间.signWith(signatureAlgorithm, secretKey);           // 签名算法以及密匙return builder.compact();
}

验证JWT

1
2
3
4
5
6
7
public static Claims parseJWT(String jwt) throws Exception {SecretKey secretKey = generalKey();return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();
}

完整示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import com.google.gson.Gson;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.tomcat.util.codec.binary.Base64;import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;public class JwtUtil {/*** 由字符串生成加密key** @return*/public SecretKey generalKey() {String stringKey = Constant.JWT_SECRET;// 本地的密码解码byte[] encodedKey = Base64.decodeBase64(stringKey);// 根据给定的字节数组使用AES加密算法构造一个密钥SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");return key;}/*** 创建jwt* @param id* @param issuer* @param subject* @param ttlMillis* @return* @throws Exception*/public String createJWT(String id, String issuer, String subject, long ttlMillis) throws Exception {// 指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;// 生成JWT的时间long nowMillis = System.currentTimeMillis();Date now = new Date(nowMillis);// 创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)Map<String, Object> claims = new HashMap<>();claims.put("uid", "123456");claims.put("user_name", "admin");claims.put("nick_name", "X-rapido");// 生成签名的时候使用的秘钥secret,切记这个秘钥不能外露哦。它就是你服务端的私钥,在任何场景都不应该流露出去。// 一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。SecretKey key = generalKey();// 下面就是在为payload添加各种标准声明和私有声明了JwtBuilder builder = Jwts.builder() // 这里其实就是new一个JwtBuilder,设置jwt的body.setClaims(claims)          // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的.setId(id)                  // 设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。.setIssuedAt(now)           // iat: jwt的签发时间.setIssuer(issuer)          // issuer:jwt签发人.setSubject(subject)        // sub(Subject):代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。.signWith(signatureAlgorithm, key); // 设置签名使用的签名算法和签名使用的秘钥// 设置过期时间if (ttlMillis >= 0) {long expMillis = nowMillis + ttlMillis;Date exp = new Date(expMillis);builder.setExpiration(exp);}return builder.compact();}/*** 解密jwt** @param jwt* @return* @throws Exception*/public Claims parseJWT(String jwt) throws Exception {SecretKey key = generalKey();  //签名秘钥,和生成的签名的秘钥一模一样Claims claims = Jwts.parser()  //得到DefaultJwtParser.setSigningKey(key)                 //设置签名的秘钥.parseClaimsJws(jwt).getBody();     //设置需要解析的jwtreturn claims;}public static void main(String[] args) {User user = new User("tingfeng", "bulingbuling", "1056856191");String subject = new Gson().toJson(user);try {JwtUtil util = new JwtUtil();String jwt = util.createJWT(Constant.JWT_ID, "Anson", subject, Constant.JWT_TTL);System.out.println("JWT:" + jwt);System.out.println("\n解密\n");Claims c = util.parseJWT(jwt);System.out.println(c.getId());System.out.println(c.getIssuedAt());System.out.println(c.getSubject());System.out.println(c.getIssuer());System.out.println(c.get("uid", String.class));} catch (Exception e) {e.printStackTrace();}}
}

常量类:Constant.java

1
2
3
4
5
6
7
8
9
10
11
import java.util.UUID;public class Constant {public static final String JWT_ID = UUID.randomUUID().toString();/*** 加密密文*/public static final String JWT_SECRET = "woyebuzhidaoxiediansha";public static final int JWT_TTL = 60*60*1000;  //millisecond
}

输出示例:

1
2
3
4
5
6
7
8
9
JWT:eyJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiIxMjM0NTYiLCJzdWIiOiJ7XCJuaWNrbmFtZVwiOlwidGluZ2ZlbmdcIixcIndlY2hhdFwiOlwiYnVsaW5nYnVsaW5nXCIsXCJxcVwiOlwiMTA1Njg1NjE5MVwifSIsInVzZXJfbmFtZSI6ImFkbWluIiwibmlja19uYW1lIjoiWC1yYXBpZG8iLCJpc3MiOiJBbnNvbiIsImV4cCI6MTUyMjMxNDEyNCwiaWF0IjoxNTIyMzEwNTI0LCJqdGkiOiJhNGQ5MjA0Zi1kYjM3LTRhZGYtODE0NS1iZGNmMDAzMzFmZjYifQ.B5wdY3_W4MZLj9uBHSYalG6vmYwdpdTXg0otdwTmU4U解密a4d9204f-db37-4adf-8145-bdcf00331ff6
Thu Mar 29 16:02:04 CST 2018
{"nickname":"tingfeng","wechat":"bulingbuling","qq":"1056856191"}
Anson
123456

一般我们把验证操作作为中间件或者拦截器就行了,请求后端API接口时候,通过过滤器获取header中的token,验证是否正确、是否过期等。

转载于:https://my.oschina.net/xiaominmin/blog/2999894

JWT学习(二):Json Web Token JWT的Java使用 (JJWT)相关推荐

  1. JSON Web Token (JWT)生成Token及解密实战

    转载自 JSON Web Token (JWT)生成Token及解密实战 昨天讲解了JWT的介绍.应用场景.优点及注意事项等,今天来个JWT具体的使用实践吧. 从JWT官网支持的类库来看,jjwt是J ...

  2. JSON Web Token (JWT),服务端信息传输安全解决方案

    转载自 JSON Web Token (JWT),服务端信息传输安全解决方案 JWT介绍 JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑独立的基于JSON对 ...

  3. php jwt token 解析,JSON Web Token(JWT)入坑详解

    JSON Web Token(JWT)入坑详解 龙行    PHP    2019-6-17    1651    0评论 /** JWT生成类 **/ class Jwt { private $al ...

  4. Json web token (JWT) golang实现

    Json web token (JWT) eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG ...

  5. (json web token)JWT攻击

    前记 最近国赛+校赛遇到两次json web token的题,发现自己做的并不算顺畅,于是有了这篇学习文章. 为什么要使用Json Web Token Json Web Token简称jwt 顾名思义 ...

  6. jwttoken解码_使用 JSON WEB TOKEN (jwt) 验证

    一.什么JSON Web Tokens? JSON Web Tokens是一种开放的行业标准  RFC 7519方法,用于在双方之间安全地表示索赔. JWT.IO允许您解码,验证和生成JWT.其中.J ...

  7. JSON Web Token(JWT)对比Opaque Token

    身份验证通常用来验证某人或某事是否如它所说的那样是谁或者是什么. 身份验证技术通过测试查看用户的凭据是否与经过身份验证的用户数据库或服务器中的凭据相匹配,从而提供设备访问控制. 基于token的身份验 ...

  8. JSON Web Token (JWT)笔记(token实现单点登录功能)

    文章目录 前情提要 cookie(储存在用户本地终端上的数据) Cookie特点: session(web服务端内存) cookie和session 单点登录(只登录一次,可使用账号下全部服务)三种方 ...

  9. 用户登入身份验证,手机app登入身份验证,TokenAuth身份验证,JSON Web Token(JWT)身份验证

                                                                        JJWT身份验证 1.pom依赖: <dependency ...

  10. JWT(JSON Web Token)简介

    文章目录 一.JWT是什么 二.跨域认证问题 三.JWT原理 四.JWT数据结构 1.header(头部) 2.Payload(负载) 3.Signature 五.JWT是如何工作的 一.JWT是什么 ...

最新文章

  1. CISCO ACL的匹配数问题
  2. 移动端也能兼容的web页面制作2:导航栏、背景图片设置
  3. ML之SVM:利用SVM算法(超参数组合进行单线程网格搜索+3fCrVa)对20类新闻文本数据集进行分类预测、评估
  4. Typora markdown公式换行等号对齐_Typora-编写博客格式化文档的最佳软件
  5. java delphi 三层_三层架构delphi+Java+Oracle模式的实现
  6. okHttp源码解析------待续
  7. html跑马灯_用Excel居然能做“跑马灯”,而且还这么简单!
  8. Python 列表 min() 方法
  9. SharePoint 2013 Step by Step——How to Create a Lookup Column to Another Site(Cross Site) 阅读目录...
  10. 代码分析测试SaaS平台Code Climate获得450万美元A轮融资
  11. EJB-02:EJB开发流程
  12. Scrum板与Kanban如何抉择?ecusiqoiw板与按照eqymgy
  13. 计算机颜色更换,如何给证件照换底色;怎么快速更换证件照底色
  14. 创建oracle自增序列
  15. 你真的了解ESD吗?老司机从零教学系列之学会ESD选型
  16. PowerBI开发 第三篇:报表设计技巧
  17. latex集合的包含_latex 集合相关符号:实数集,整数集,并,包含,真包含
  18. java程序设计高级教程答案_Java高级程序设计实战教程答案
  19. uniapp+uniCloud实现批量上传图片到云端(解决h5端跨域问题)
  20. Windows Batch 常用命令

热门文章

  1. 2018.11.09 bzoj4773: 负环(倍增+floyd)
  2. ytkah网站建设解决方案 大中小微企业营销利器
  3. 使用javascript实现html页面直接下载网盘文件
  4. java 修饰符全解
  5. 最基础eacharts图带数字,百分比,tab切换
  6. mybatis PageBounds应用分页
  7. 网络编程+并发编程总结
  8. Java 学习 day04
  9. WPF XMAL获取元素的父元素,子元素
  10. 【前台技术】-播放音频