开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 12 天,点击查看活动详情
自己去年做了一个个人网站 workp.vip.cpolar.cn
年前回家的时候发布了最新版本,昨天登录我的网站的时候发现怎么都登录失败,一直报错:token登录失败。最后通过服务器日志定位了问题,
原来是我登录时产生的token过期了。
下面是我的JwtUtil工具类
public final class JwtUtil{
private final static Calendar INSTANCE = Calendar.getInstance();
static {
// 默认7天登录有效期
INSTANCE.add(Calendar.DATE, 7);
}
/**
* 根据payload(也就是clamis)获取token字符串
*
* @param claims payload的数据集合
* @return token
*/
public static String getToken(Map<String, Object> claims) throws UnsupportedEncodingException {
return getToken(claims, INSTANCE.getTime());
}
}
JwtUtil中我把Calendar定义成了一个静态的成员变量,这样就导致INSTANCE实例永远是启动时刻的时间。而我是去年启动的项目,之前开发的时候经常两三天会重启一次项目调整Bug。我的token是7天过期,所以之前我没有发现这个Bug。
而过年回来之后,我的登录Token早已经过期了,当我重新登录的时候,新的Token还是基于去年时间段(一月份)生成的,那么过期时间就是去年启动时间+7天(还是一月),所以无论怎样都会登录失败,报错token过期。
解决方案
我们通常都是通过Calendar类来计算日期,虽然它的API有很多不完善的地方,但是使用它计算简单的日期还是可以的。最终解决方案就是把静态实例定义成方法的局部变量。每次生成token时都获取最新时间。
public static String getToken(Map<String, Object> claims) throws UnsupportedEncodingException {
return getToken(claims, getExpireDate());
}
public static Date getExpireDate(){
Calendar instance = Calendar.getInstance();
instance.add(Calendar.DATE, 7);
return instance.getTime();
}
结语
看来static使用不当,很容易引发不知情的Bug呀。Bug仍未消除完毕,同志们仍需努力!加油~