总结
token的签名(生成token),解码(根据私钥和算法),判定token有效性、得到负载信息
好处
跨域(请求头中)
无状态化(不需要持久化)
依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
</dependency>
生成token
public static String sign(String username, String userId) {
try {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET); //根据私钥生成算法
Map<String, Object> header = new HashMap<>(2);
header.put("typ", "JWT");
header.put("alg", "HS256");
return JWT.create().
withHeader(header).
withClaim("loginName", username).
withClaim("userId", userId).
withExpiresAt(date).sign(algorithm);
} catch (UnsupportedEncodingException e) {
return null;
}
}
private static final long EXPIRE_TIME = 24 * 60 * 60 * 1000; //过期时间
private static final String TOKEN_SECRET = "f26e587c28064d0e855e72c0a6a0e618"; //私钥
认证
@GetMapping("/login")
@ResponseBody
public String login(User user) {
String loginName = map.get("username");
String password = map.get("password");
boolean isSuccess = service.hasUserByUsernameAndPassword(username, password);
if (isSuccess) {
User user = userService.getUserByLoginName(loginName);
if (user != null) {
String token = JwtUtil.sign(user.getName(), user.getId());
if (token != null) return token;
}
}
return "success";
}
拦截器配置(获取token,查看缓存中是否存在该token)
public class TokenInterceptor implements HandlerInterceptor { @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("access_token");
if (token != null) {
boolean result = JwtUtil.verify(token);
if (result) {
return true;
}
}
}
}
放行认证接口
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/login/"/>
<bean class="com.joe.interceptor.TokenInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
验证token的有效性
public static boolean verify(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception exception) {
return false;
}
}
获取负载信息
public static String getUsername(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim("loginName").asString();
} catch (JWTDecodeException e) {
return null;
}
}