JWT令牌的入门与使用

在分布式的项目中,资源服务的访问需要带着用户的token去认证服务器进行用户的认证再返回给用户所请求的资源,但资源服务器与认证服务器之间频繁的网络通信会造成性能上的开销。

JWT令牌的入门与使用_第1张图片

相比于传统的只作为用户唯一标识的token,jwt(json web token)可以携带用户的信息,当用户使用jwt令牌访问资源服务器的时候,资源服务器可直接使用公钥进行令牌携带信息的校验,从而可以减少认证服务器的开销。

JWT令牌的入门与使用_第2张图片

 

jwt令牌结构


JWT令牌由三部分组成,每部分中间使用点(.)分隔,比如:xxxxx.yyyyy.zzzzz

Header

头部包括令牌的类型(即JWT)及使用的哈希算法(如HMAC SHA256或RSA)
下边是Header部分的内容

{
"alg": "HS256",
"typ": "JWT"
}
将上边的内容使用Base64Url编码,得到一个字符串就是JWT令牌的第一部分。

Payload

第二部分是负载,内容也是一个json对象,它是存放有效信息的地方,它可以存放jwt提供的现成字段,比
如:iss(签发者),exp(过期时间戳), sub(面向的用户)等,也可自定义字段。
此部分不建议存放敏感信息,因为此部分可以解码还原原始内容。

{
"sub": "1234567890",
"name": "456",
"admin": true
}
最后将第二部分负载使用Base64Url编码,得到一个字符串就是JWT令牌的第二部分。

Signature

第三部分是签名,此部分用于防止jwt内容被篡改。
这个部分使用base64url将前两部分进行编码,编码后使用点(.)连接组成字符串,最后使用header中声明
签名算法进行签名。

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

base64UrlEncode(header):jwt令牌的第一部分。
base64UrlEncode(payload):jwt令牌的第二部分。
secret:签名所使用的密钥。

 

jwt令牌管理


1、生成密钥证书


下边使用keytool生成密钥证书,采用RSA 算法每个证书包含公钥和私钥

keytool -genkeypair -alias mykey -keyalg RSA -keypass abc123 -keystore my.keystore -storepass abc123

Keytool 是一个java提供的证书管理工具
-alias:密钥的别名
-keyalg:使用的hash算法
-keypass:密钥的访问密码
-keystore:密钥库文件名,my.keystore保存了生成的证书
-storepass:密钥库的访问密码

查询证书信息:

keytool -list -keystore my.keystore

删除别名:

keytool -delete -alias mykey -keystore my.keystore

 

2、公私钥证书导入导出不再赘述,使用openssl

 

3、生成jwt令牌

//生成一个jwt令牌
@Test
public void testCreateJwt(){
//证书文件
String key_location = "my.keystore";
//密钥库密码
String keystore_password = "abc23";
//访问证书路径
ClassPathResource resource = new ClassPathResource(key_location);
//密钥工厂
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource,keystore_password.toCharArray());
String keypassword = "abc23";
//密钥别名
String alias = "mykey";
//密钥对(密钥和公钥)
KeyPair keyPair = keyStoreKeyFactory.getKeyPair(alias,keypassword.toCharArray());
//私钥
RSAPrivateKey aPrivate = (RSAPrivateKey) keyPair.getPrivate();
//定义payload信息
Map tokenMap = new HashMap<>();
tokenMap.put("id", "123");
tokenMap.put("name", "mrt");
tokenMap.put("roles", "r01,r02");
tokenMap.put("ext", "1");
//生成jwt令牌
Jwt jwt = JwtHelper.encode(JSON.toJSONString(tokenMap), new RsaSigner(aPrivate));
//取出jwt令牌
String token = jwt.getEncoded();
System.out.println("token="+token);
}

4、验证jwt令牌

//资源服务使用公钥验证jwt的合法性,并对jwt解码
@Test
public void testVerify(){
//jwt令牌
String token
="你的令牌";
//公钥
String publickey = "你的公钥";
//校验jwt
Jwt jwt = JwtHelper.decodeAndVerify(token, new RsaVerifier(publickey));
//获取jwt原始内容
String claims = jwt.getClaims();
//jwt令牌
String encoded = jwt.getEncoded();
System.out.println(encoded);
}

 

你可能感兴趣的:(JWT令牌的入门与使用)