Token的组成header.poyload.sign
header:头部,包括参数类型(JWT),签名算法(HS256);
poyload:负荷,存放信息(信息容易暴漏,不应该在载荷里面加敏感数据);
sign:签名,Hs256(header(base64)+poyload(base64))加密;
token生成方式两种 *不借助第三方jar,自己生成token;
*借助第三方jar传入需要得负荷信息,生成token;
1>自己生成token;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class HS256 {
public static String returnSign(String message) {
String hash = "";
//别人篡改数据,但是签名的密匙是在服务器存储,密匙不同,生成的sign也不同。
//所以根据sign的不同就可以知道是否篡改了数据。
String secret = "mystar";//密匙
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(),"HmacSHA256");
sha256_HMAC.init(secret_key);
hash = Base64.encodeBase64String(sha256_HMAC.doFinal(message.getBytes()));
System.out.println(message+"#####"+hash);
} catch (Exception e) {
System.out.println("Error");
}
return hash;
}
}
这样token的三部分就生成了,然后当做参数传到前台,用cookie存储就可以在同一客户端调用了。
当从客户端带过来token参数的时候,直接对头部和负荷再次调用加密算法,看生成的新的签名和之前的签名是否一致,
判断数据是否被篡改。
2>
借用第三方的jar(jjwt-0.9.0.jar)生成token;
token负荷参数:
负荷参数:
public class JwtToken {
private String userId;
private String userName;
private String uuid = UUID.randomUUID().toString();
}
//token容器
public class TokenContainer {
//存储token
private ConcurrentHashMap<String, String> tokenMap = new ConcurrentHashMap<String, String>();
public void addToken(String token,String userId){
tokenMap.put(userId, token);
}
public ConcurrentHashMap<String,String> getTokenMap(){
return tokenMap;
}
private TokenContainer(){
}
public static TokenContainer newInstance(){
return Builder.iContainer;
}
private static class Builder{
private static TokenContainer iContainer = new TokenContainer();
}
}
TokenContainer {
//存储token
private ConcurrentHashMap<String, String> tokenMap = new ConcurrentHashMap<String, String>();
public void addToken(String token,String userId){
tokenMap.put(userId, token);
}
public ConcurrentHashMap<String,String> getTokenMap(){
return tokenMap;
}
private TokenContainer(){
}
public static TokenContainer newInstance(){
return Builder.iContainer;
}
private static class Builder{
private static TokenContainer iContainer = new TokenContainer();
}
}
// 使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
public static String createJavaWebToken(JwtToken token) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 3);// 过期时间3天
Map<String, Object> claims = new HashMap<String, Object>();
claims.put("userId", token.getUserId());
claims.put("uuid", token.getUuid());
String tokenStr = Jwts.builder().setClaims(claims).setExpiration(
calendar.getTime()).// 设置过期时间
signWith(SignatureAlgorithm.HS256, getKeyInstance()).compact();
TokenContainer.newInstance().addToken(tokenStr, token.getUserId());
return tokenStr;
}
// 使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
public static String createJavaWebToken(JwtToken token) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 3);// 过期时间3天
Map<String, Object> claims = new HashMap<String, Object>();
claims.put("userId", token.getUserId());
claims.put("uuid", token.getUuid());
String tokenStr = Jwts.builder().setClaims(claims).setExpiration(
calendar.getTime()).// 设置过期时间
signWith(SignatureAlgorithm.HS256, getKeyInstance()).compact();
TokenContainer.newInstance().addToken(tokenStr, token.getUserId());
return tokenStr;
}
认证token:
// 该方法使用HS256算法和Secret:keyStr生成signKey
private static Key getKeyInstance() {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(keyStr);//keyStr = "lyf@we%sd(888)"
Key signingKey = new SecretKeySpec(apiKeySecretBytes,
signatureAlgorithm.getJcaName());
return signingKey;
}
private static Key getKeyInstance() {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(keyStr);//keyStr = "lyf@we%sd(888)"
Key signingKey = new SecretKeySpec(apiKeySecretBytes,
signatureAlgorithm.getJcaName());
return signingKey;
}
// 解析Token,同时也能验证Token,当验证失败返回null
public static JwtToken parserJavaWebToken(String jwt) {
try {
JwtToken jsJwtToken = null;
Map<String, Object> jwtClaims = Jwts.parser().setSigningKey(
getKeyInstance()).parseClaimsJws(jwt).getBody();//密钥
if (null != jwtClaims) {
jsJwtToken = new JwtToken();
jsJwtToken.setUserId(jwtClaims.get("userId").toString());
}
return jsJwtToken;
} catch (Exception e) {
return null;
}
}
public static JwtToken parserJavaWebToken(String jwt) {
try {
JwtToken jsJwtToken = null;
Map<String, Object> jwtClaims = Jwts.parser().setSigningKey(
getKeyInstance()).parseClaimsJws(jwt).getBody();//密钥
if (null != jwtClaims) {
jsJwtToken = new JwtToken();
jsJwtToken.setUserId(jwtClaims.get("userId").toString());
}
return jsJwtToken;
} catch (Exception e) {
return null;
}
}
最后调用parserJavaWebToken验证token是否存在;