JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的 信息。在Java世界中通过JJWT实现JWT创建和验证。
io.jsonwebtoken
jjwt
0.7.0
public static void main(String[] args) {
JwtBuilder builder= Jwts.builder()
.setId("1")
.setSubject("admin")
.setIssuedAt(new Date())
//指定签名加密类型和密钥
.signWith(SignatureAlgorithm.HS256,"123456");
//生成token
String token = builder.compact();
System.out.println(token);
}
运行结果如下:
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwic3ViIjoiYWRtaW4iLCJpYXQiOjE1OTM5NTE5NjN9.QcLKWVUOa15EaSAHyLAIkBooxzWtZmaz6HG2nIdubUI
解析时使用的密钥要和生成token时使用的密钥一致,不然会报错。
public static void main(String[] args) {
String token =
"eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwic3ViIjoiYWRtaW4iLCJpYXQiOjE1OTM5NTE5NjN9.QcLKWVUOa15EaSAHyLAIkBooxzWtZmaz6HG2nIdubUI";
Claims claims = Jwts.parser()
.setSigningKey("123456") //设置密钥
.parseClaimsJws(token).getBody();
System.out.println(claims.getId());
System.out.println(claims.getSubject());
System.out.println(claims.getIssuedAt());
}
结果如下
和生成使用的信息一致。
自定义claims使用claim(String name, Object value)方法,解析使用get(Object key);
long exp = System.currentTimeMillis() + 1000 * 60;//当前时间
JwtBuilder builder= Jwts.builder()
.setId("1")
.setSubject("admin")
.setIssuedAt(new Date())
.claim("roles", "admin")
.setExpiration(new Date(exp))
//指定签名加密类型和密钥
.signWith(SignatureAlgorithm.HS256, "123456");
//生成token
String token = builder.compact();
System.out.println(token);
解析
Claims claims = Jwts.parser()
.setSigningKey("123456") //设置密钥
.parseClaimsJws(token).getBody();
System.out.println("roles:" + claims.get("roles"));
@Getter
@Setter
@ConfigurationProperties("jwt.config")
public class JwtUtils {
//签名私钥
private String key;
//签名的失效时间
private Long ttl;
/**
* 设置认证token
* id:登录用户id
* subject:登录用户名
*
*/
public String createJwt(String id, String name, Map map) {
//1.设置失效时间
long now = System.currentTimeMillis();//当前毫秒
long exp = now + ttl;
//2.创建jwtBuilder
JwtBuilder jwtBuilder = Jwts.builder().setId(id).setSubject(name)
.setIssuedAt(new Date())
.signWith(SignatureAlgorithm.HS256, key);
//3.根据map设置claims
for(Map.Entry entry : map.entrySet()) {
jwtBuilder.claim(entry.getKey(),entry.getValue());
}
jwtBuilder.setExpiration(new Date(exp));
//4.创建token
String token = jwtBuilder.compact();
return token;
}
/**
* 解析token字符串获取clamis
*/
public Claims parseJwt(String token) {
Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
return claims;
}
}
修改application.yml, 添加配置
jwt: config: key: springboot-test ttl: 360000
1.前端输入用户名和密码发送登入请求,后台拿到前端发送的进行验证成功后生成token,并相应返回token。
2.之后前端发送请求需带上token。
前后端约定:前端请求微服务时需要添加头信息Authorization ,内容为Bearer+空格+token
String authorization = request.getHeader("Authorization");
//前后端约定头信息内容以 Bearer+空格+token 形式组成
String token = authorization.replace("Bearer ", "");
//比较并获取claims
Claims claims = jwtUtil.parseJWT(token);
if(claims == null) {
throw new CommonException(ResultCode.UNAUTHENTICATED);
}
System.out.println("id:" + claims.getId());
System.out.println("subject:" + claims.getSubject());
System.out.println("IssuedAt:" + claims.getIssuedAt());
System.out.println("roles:" + claims.get("roles"));
//验证相关角色和权限等等。。。
对于token解析一般都在拦截器中进行处理。然后再处理请求逻辑