JWT全称为JSON Web Token,是目前最流行的跨域身份验证解决方案。JWT是为了在网络应用环境间传递声明而制定的一种基于JSON的开放标准。
JWT特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可被加密。
jwt就是很长的json字符串,字符串之间用.分隔3个子串。每个子串表示一个功能块,jwt头(header)、有效载荷(payload)、签名(signature)
我们看上去这些字符不是json字符串是因为进行了base64加密后再拼接的
1、JWT头
2、有效载荷(主体内容)
3、签名(为了加密的过程)
HS256对称加密算法,双方之间共享一个密钥,生成和验证都是一个密钥,因此必须注意密钥的安全
RS256非对称加密算法,用公共/私钥对jwt提供方采用私钥生成,jwt使用方获取公钥验证(更安全,服务方生成,私钥保存在服务器更安全)
就是个提供jwt创建和验证的java库
要导入对应的maven坐标使用
- <dependency>
- <groupId>io.jsonwebtokengroupId>
- <artifactId>jjwtartifactId>
- <version>0.9.1version>
- dependency>
1、先导入jjwt和junit的依赖
2、编写单元测试
- import cn.hutool.core.io.FileUtil;
- import io.jsonwebtoken.*;
- import org.junit.Test;
- import java.io.DataInputStream;
- import java.io.InputStream;
- import java.security.*;
- import java.security.spec.PKCS8EncodedKeySpec;
- import java.security.spec.X509EncodedKeySpec;
- import java.util.HashMap;
- import java.util.Map;
-
- public class JwtTest {
- //生成jwt,不使用签名
- @Test
- public void test1(){
- //添加构成JWT的参数
- Map
headMap = new HashMap(); - headMap.put("alg", "none");//不使用签名算法
- headMap.put("typ", "JWT");
-
- Map body = new HashMap();
- body.put("userId","1");
- body.put("username","xiaoming");
- body.put("role","admin");
- //用jjwt提供api生成jwt令牌
- String jwt = Jwts.builder()
- .setHeader(headMap)
- .setClaims(body)
- .setId("jwt001")
- .compact();
- System.out.println(jwt);
-
- //解析jwt
- Jwt result = Jwts.parser().parse(jwt);
- Object jwtBody = result.getBody();
- Header header = result.getHeader();
-
- System.out.println(result);
- System.out.println(jwtBody);
- System.out.println(header);
- }
-
- //生成jwt时使用签名算法生成签名部分----基于HS256签名算法
- @Test
- public void test2(){
- //添加构成JWT的参数
- Map
headMap = new HashMap(); - headMap.put("alg", SignatureAlgorithm.HS256.getValue());//使用HS256签名算法
- headMap.put("typ", "JWT");
-
- Map body = new HashMap();
- body.put("userId","1");
- body.put("username","xiaoming");
- body.put("role","admin");
- //用jjwt提供api生成jwt令牌
- String jwt = Jwts.builder()
- .setHeader(headMap)
- .setClaims(body)
- .setId("jwt001")
- .signWith(SignatureAlgorithm.HS256,"itcast")
- .compact();
- System.out.println(jwt);
-
- //解析jwt
- Jwt result = Jwts.parser().setSigningKey("itcast").parse(jwt);
- Object jwtBody = result.getBody();
- Header header = result.getHeader();
-
- System.out.println(result);
- System.out.println(jwtBody);
- System.out.println(header);
- }
-
- //生成jwt时使用签名算法生成签名部分----基于RS256签名算法
- @Test
- public void test3() throws Exception{
- //添加构成JWT的参数
- Map
headMap = new HashMap(); - headMap.put("alg", SignatureAlgorithm.RS256.getValue());//使用RS256签名算法
- headMap.put("typ", "JWT");
-
- Map body = new HashMap();
- body.put("userId","1");
- body.put("username","xiaoming");
- body.put("role","admin");
-
- String jwt = Jwts.builder()
- .setHeader(headMap)
- .setClaims(body)
- .setId("jwt001")
- .signWith(SignatureAlgorithm.RS256,getPriKey())
- .compact();
- System.out.println(jwt);
-
- //解析jwt
- Jwt result = Jwts.parser().setSigningKey(getPubKey()).parse(jwt);
- Object jwtBody = result.getBody();
- Header header = result.getHeader();
-
- System.out.println(result);
- System.out.println(jwtBody);
- System.out.println(header);
- }
-
- //获取私钥
- public PrivateKey getPriKey() throws Exception{
- InputStream resourceAsStream =
- this.getClass().getClassLoader().getResourceAsStream("pri.key");
- DataInputStream dis = new DataInputStream(resourceAsStream);
- byte[] keyBytes = new byte[resourceAsStream.available()];
- dis.readFully(keyBytes);
- PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
- KeyFactory kf = KeyFactory.getInstance("RSA");
- return kf.generatePrivate(spec);
- }
-
- //获取公钥
- public PublicKey getPubKey() throws Exception{
- InputStream resourceAsStream =
- this.getClass().getClassLoader().getResourceAsStream("pub.key");
- DataInputStream dis = new DataInputStream(resourceAsStream);
- byte[] keyBytes = new byte[resourceAsStream.available()];
- dis.readFully(keyBytes);
- X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
- KeyFactory kf = KeyFactory.getInstance("RSA");
- return kf.generatePublic(spec);
- }
-
- //生成自己的 秘钥/公钥 对
- @Test
- public void test4() throws Exception{
- //自定义 随机密码, 请修改这里
- String password = "itcast";
-
- KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
- SecureRandom secureRandom = new SecureRandom(password.getBytes());
- keyPairGenerator.initialize(1024, secureRandom);
- KeyPair keyPair = keyPairGenerator.genKeyPair();
-
- byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
- byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
-
- FileUtil.writeBytes(publicKeyBytes, "d:\\pub.key");
- FileUtil.writeBytes(privateKeyBytes, "d:\\pri.key");
- }
- }