一、绪论
Java开发过程中,很多接口的访问需要进行权限校验,我们经常遇到的是在访问一个接口之前需要获取到系统的访问token,然后携带token继续访问业务接口、那么这个token是怎样的生成的。下面介绍通过JWTUtil工具生成的token和校验。
二、JWTUtil介绍
JWT是一种开放标准(open standard),它定义了一种紧凑且自包含的方式来在不同的应用程序之间安全地传递信息。
JWT由三部分组成:头部(header)、载荷(payload)和签名(signature)。头部包含算法和令牌类型,载荷包含有关用户的信息,签名是对头部和载荷进行哈希处理的结果,以确保它们在传输过程中没有被篡改。
JWTUTIL工具类
package com.rb.jwtdemo.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
public class JwtUtils {
private static final String secret="secretStr";//自定义密钥,越复杂安全性越高
// 生成JWT令牌
/**
* 生成JWT令牌
* @param map payload
* @param expiresDay 过期时间(天)
* @return token
*/
public static String generateJwtToken(Map<String,String> map,int expiresDay) {
Algorithm algorithm = Algorithm.HMAC256(secret);
Date now = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
calendar.add(Calendar.DATE, expiresDay);//设置过期时间
Date expiresAt = calendar.getTime();
JWTCreator.Builder builder = JWT.create();
map.forEach(builder::withClaim);//设置payload
builder.withExpiresAt(expiresAt);//设置过期时间
return builder.sign(algorithm);
}
/**
* 验证JWT令牌
* @param token
* @return
*/
public static boolean validateJwtToken(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWT.require(algorithm).build().verify(token);
return true;//token验证通过
}catch (Exception e) {
return false;//token验证通过
}
}
/**
* 解析JWT令牌中的信息
* @param token
* @return
*/
// 解析JWT令牌中的信息
public static DecodedJWT parseJwtToken(String token) {
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.require(algorithm).build().verify(token);
}
}
package com.rb.jwtdemo.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
public class JwtUtils {
private static final String secret="secretStr";//自定义密钥,越复杂安全性越高
// 生成JWT令牌
/**
* 生成JWT令牌
* @param map payload
* @param expiresDay 过期时间(天)
* @return token
*/
public static String generateJwtToken(Map<String,String> map,int expiresDay) {
Algorithm algorithm = Algorithm.HMAC256(secret);
Date now = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
calendar.add(Calendar.DATE, expiresDay);//设置过期时间
Date expiresAt = calendar.getTime();
JWTCreator.Builder builder = JWT.create();
map.forEach(builder::withClaim);//设置payload
builder.withExpiresAt(expiresAt);//设置过期时间
return builder.sign(algorithm);
}
/**
* 验证JWT令牌
* @param token
* @return
*/
public static boolean validateJwtToken(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWT.require(algorithm).build().verify(token);
return true;//token验证通过
}catch (Exception e) {
return false;//token验证通过
}
}
/**
* 解析JWT令牌中的信息
* @param token
* @return
*/
// 解析JWT令牌中的信息
public static DecodedJWT parseJwtToken(String token) {
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.require(algorithm).build().verify(token);
}
}
三、校验与测试
@Test
void create() {
Map map=new HashMap<>();
map.put("userNo","123456");
map.put("userName","张三");
map.put("userType","1");
String token = JwtUtils.generateJwtToken(map, 1);
System.out.println(token);
}
@Test
void decode(){
String token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyTm8iOiIxMjM0NTYiLCJ1c2VyVHlwZSI6IjEiLCJ1c2VyTmFtZSI6IuW8oOS4iSIsImV4cCI6MTY4MDY4NDY5OH0.9O5oOTYwEZxB6AeAPmcLIabxWIvyB_dVpX3S1IGdTVA";
if(JwtUtils.validateJwtToken(token)){
DecodedJWT decodedJWT = JwtUtils.parseJwtToken(token);
System.out.println(decodedJWT.getClaim("userNo").asString());
System.out.println(decodedJWT.getClaim("userName").asString());
System.out.println(decodedJWT.getClaim("userType").asString());
}else {
System.out.println("token验证失败");
}
}
@Test
void create() {
Map map=new HashMap<>();
map.put("userNo","123456");
map.put("userName","张三");
map.put("userType","1");
String token = JwtUtils.generateJwtToken(map, 1);
System.out.println(token);
}
@Test
void decode(){
String token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyTm8iOiIxMjM0NTYiLCJ1c2VyVHlwZSI6IjEiLCJ1c2VyTmFtZSI6IuW8oOS4iSIsImV4cCI6MTY4MDY4NDY5OH0.9O5oOTYwEZxB6AeAPmcLIabxWIvyB_dVpX3S1IGdTVA";
if(JwtUtils.validateJwtToken(token)){
DecodedJWT decodedJWT = JwtUtils.parseJwtToken(token);
System.out.println(decodedJWT.getClaim("userNo").asString());
System.out.println(decodedJWT.getClaim("userName").asString());
System.out.println(decodedJWT.getClaim("userType").asString());
}else {
System.out.println("token验证失败");
}
}
四、第二中方式
package cn.hutool.jwt;
import cn.hutool.jwt.signers.JWTSigner;
import java.util.Map;
/**
* JSON Web Token (JWT)工具类
*/
public class JWTUtil {
/**
* 创建HS256(HmacSHA256) JWT Token
*
* @param payload 荷载信息
* @param key HS256(HmacSHA256)密钥
* @return JWT Token
*/
public static String createToken(Map<String, Object> payload, byte[] key) {
return createToken(null, payload, key);
}
/**
* 创建HS256(HmacSHA256) JWT Token
*
* @param headers 头信息
* @param payload 荷载信息
* @param key HS256(HmacSHA256)密钥
* @return JWT Token
*/
public static String createToken(Map<String, Object> headers, Map<String, Object> payload, byte[] key) {
return JWT.create()
.addHeaders(headers)
.addPayloads(payload)
.setKey(key)
.sign();
}
/**
* 创建JWT Token
*
* @param payload 荷载信息
* @param signer 签名算法
* @return JWT Token
*/
public static String createToken(Map<String, Object> payload, JWTSigner signer) {
return createToken(null, payload, signer);
}
/**
* 创建JWT Token
*
* @param headers 头信息
* @param payload 荷载信息
* @param signer 签名算法
* @return JWT Token
*/
public static String createToken(Map<String, Object> headers, Map<String, Object> payload, JWTSigner signer) {
return JWT.create()
.addHeaders(headers)
.addPayloads(payload)
.setSigner(signer)
.sign();
}
/**
* 解析JWT Token
*
* @param token token
* @return {@link JWT}
*/
public static JWT parseToken(String token) {
return JWT.of(token);
}
/**
* 验证JWT Token有效性
*
* @param token JWT Token
* @param key HS256(HmacSHA256)密钥
* @return 是否有效
*/
public static boolean verify(String token, byte[] key) {
return JWT.of(token).setKey(key).verify();
}
/**
* 验证JWT Token有效性
*
* @param token JWT Token
* @param signer 签名器
* @return 是否有效
*/
public static boolean verify(String token, JWTSigner signer) {
return JWT.of(token).verify(signer);
}
}
生成token
String message = JWTUtil.createToken(map, password.getBytes());
校验token示例:
/**
* 获取登录用户token解密信息
*/
public static WXModelInfoDTO WXModelInfo() {
HttpServletRequest request = getHttpServletRequest();
if (request == null || request.getSession() == null) {
return null;
}
// 判断token是否过期
String token = request.getHeader(Constant.resToken);
if (StrUtil.isBlank(token)) {
return null;
}
String jwtToken = RsaUtils.privateDecrypt(token, RAS_PRIVATE_KEY);
JWT jwt = JWTUtil.parseToken(jwtToken);
WXModelInfoDTO wxModelInfoDto = redisUtils.get(String.valueOf(jwt.getPayload(Constant.sessionKey)),
WXModelInfoDTO.class, EXPIRE_DATE);
return wxModelInfoDto;
}