1、token解析
token分为三部分来定义:
1 .表头:Header是一个json对象,存储元数据(可逆)
由以下组成:
{
"alg":"HS256",
"typ":"JWT"
}
alg:是签名的算法名称(algorithm),默认是HMAC SHA);
type属性表示这个令牌(token)的类型(type),JWT令牌统一写成JWT。
2.负载:Payload是一个json对象。存放传递的数据,数据分为Public和Private。(可逆)
Public是JWT中规定的一些字段,可以自己选择使用。
iss(issuer):签发人
exp(expiration time):过期时间
sub(subject):该JWT所面向的用户
aud(audience):受众,接受该JWT的一方
nbf(not before):生效时间
iat(Issued At):签发时间
jti(JWT ID):编号
Privote是自己定义的字段
{
“role":经理,
"name":张凡,
"id":23455
}
Payload默认是没有加密的,以上数据都是明文传输的,所以最好不要存放敏感数据。
【注】前两部分数据都是json对象使用的是base64URL编码,翻译为字符串。
3.Signature:签名。签名是对Header和Payload两部分的签名,目的是为了防止数据被篡改(不可逆)
HMACSHA256(
base64UrlEncoder(header)+"."+
base64UrlENcode(paylosd),
secret)
签名算法:先指定一个secret密匙,把base64URL的header,base64RL的payload和secret秘匙 使用HNAC SHA256生成签名字符串。
最后把三个部分的拼成一个字符串,每个部分之间用点(.)分隔,就可以返回给用户
如:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhcGlfa2V5IjoiWmh1YW5BbiIsImV4cCI6MzU5NzA1NDE5NywiYXBpX3NlY3JldCI6InpodWFuYW4yMDIyIn0.e081v0pU9k4jfSGNFtRbwYJfWggZiR2DO385ClKhKCY
2、token生成以及验证的例子
package com.ruoyi.framework.jwt.utils;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.usermodel.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
public class test {
public static final String API_KEY = "api_key";
public static final String API_SECRET = "api_secret";
public static final String HEADS_TYPE_KEY = "type";
public static final String HEADS_TYPE_VALUE = "jwt";
public static final String HEADS_ALGORITHM_KEY = "alg";
public static final String HEADS_ALGORITHM_VALUE = "HS256";
public static final String AUTH_HEAD = "Authentication";
public static final String SALT = "AWER@#$@";
/**
* 生产token
* @param api_key 约定
* @param api_secret 约定
* @param time token过期时间,毫秒
*/
public static String generateToken(String api_key, String api_secret, Long time){
String token = null;
try {
//设置token过期时间 :如果想每次生成的token一样,这里的起始时间就写死
//Date date = new Date(System.currentTimeMillis()+time);
Date date = new Date(new Date().getTime()+time);
//设置加密算法
Algorithm algorithm = Algorithm.HMAC256(SALT);
//设置头部
/**
* {
* “type”: “JWT”, 声明类型,这里是jwt
* “alg”: “HS256” 声明加密的算法 通常直接使用 HMAC SHA256
* }
*/
Map<String ,Object> headers = new HashMap<>();
headers.put(HEADS_TYPE_KEY,HEADS_TYPE_VALUE);
headers.put(HEADS_ALGORITHM_KEY,HEADS_ALGORITHM_VALUE);
//生产token
token = JWT.create()
.withClaim(API_KEY,api_key)
.withClaim(API_SECRET,api_secret)
.withExpiresAt(date)
.sign(algorithm);
} catch (Exception e) {
}
return token; }
/**
* 校验token
* @param token 需要校验的token
*/
public static boolean verification(String token){
try {
//根据盐获取加解密算法
Algorithm algorithm = Algorithm.HMAC256(SALT);
//获取解密对象
JWTVerifier jwtVerifier = JWT.require(algorithm).build();
//解密
DecodedJWT decodedJWT = jwtVerifier.verify(token);
//获取客户信息
return true;
}catch (Exception e){
return false;
}
}
//测试
public static void main(String[] args) throws Exception {
//过期时间60年
String token = test.generateToken("刘伟", "aaa@", 60*12*31*24*60*60 * 1000L);
boolean result = test.verification("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhcGlfa2V5IjoiWmh1YW5BbiIsImV4cCI6MzU5NzA1NDE5NywiYXBpX3NlY3JldCI6InpodWFuYW4yMDIyIn0.e081v0pU9k4jfSGNFtRbwYJfWggZiR2DO385ClKhKCY");
System.out.println(token);
System.out.println(result);
}
}