项目需要在kong实现token的校验,因此研究了一下kong的jwt插件的使用方式。
目前的做法是,用户登录通过前端调用java接口(该接口无需token校验),在java端验证通过后,返回一个token到前端,此后前端的请求都需要根据返回的token进行校验。
校验的逻辑放到kong,由kong来判断当前token是否合法,是否过期等。
实现静态变量通过配置文件注入
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Component
public class TokenUtil {
private static String JWTKEY;
private static String JWTSECRET;
private static Long LASTTIME ;
@Value("${kong.jwt.key}")
public void setJWTKEY(String JWTKEY) {
TokenUtil.JWTKEY = JWTKEY;
}
@Value("${kong.jwt.secret}")
public void setJWTSECRET(String JWTSECRET) {
TokenUtil.JWTSECRET = JWTSECRET;
}
@Value("${kong.jwt.exp}")
public void setLASTTIME(Long LASTTIME) {
TokenUtil.LASTTIME = LASTTIME;
}
/**
* 解密
*
* @param jsonWebToken
* @param base64Security
* @return
*/
public static Claims parseJWT(String jsonWebToken,String base64Security) {
try {
Claims claims =Jwts.parser()
.setSigningKey(base64Security.getBytes())
.parseClaimsJws(jsonWebToken).getBody();
return claims;
}catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
/**
* @param useInfo 需要token携带的信息
* @return
*/
public static String createJWT(Map useInfo) {
//添加构成JWT的参数
try {
Algorithm algorithm =Algorithm.HMAC256(JWTSECRET);
Map headerClaims =new HashMap();
headerClaims.put("alg","HS256");
headerClaims.put("typ","JWT");
Date date =new Date();
date.setTime(date.getTime() +LASTTIME);
// iss:定义jwt的(多个)签发者(验证的时候判断是否是签发者)
// sub:定义jwt的所有者(验证的时候判断是否是所有者)
// aud:定义jwt的(多个)接收方(验证的时候判断我是否是其中一员)
// exp:定义jwt的过期时间,它必须大于jwt的签发时间
// nbf:定义jwt的生效时间
// iat:定义jwt的签发时间,claims_to_verify配置参数不允许设置iat
// jti:jwt唯一身份标识,主要用来作为一次性token来使用,从而回避重放攻击
JWTCreator.Builder builder =JWT.create()
.withHeader(headerClaims)
.withClaim("iss",JWTKEY)
.withClaim("exp", date)
.withClaim("nbf",new Date())
.withClaim("iat",new Date());
Iterator> entries = useInfo.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = entries.next();
builder.withClaim(entry.getKey(),entry.getValue());
}
String token = builder.sign(algorithm);
return token;
}catch (JWTCreationException exception) {
//Invalid Signing configuration / Couldn't convert Claims.
}
return null;
}
public static void main(String[] args) {
Map map =new HashMap();
map.put("userCode","abv");
map.put("userCode2","abc");
//密钥
String keyt =JWTSECRET;
String token =createJWT(map);
System.out.println("JWT加密的结果:" + token);
System.out.println("JWT解密的结果:" +parseJWT(token, keyt));
}
}
因为看到很多地方只写到了通过https://jwt.io/ 该网址去调试token,没有说明java代码应该如何实现才能得到一个通过jwt校验的语句。
KONG配置如下
1、先按照插件到kong
2、设置好参数,iss是默认就有的
3、找到当前consumer对应的key与secret,对应java代码的JWTKEY,JWTSECRET常量