什么是token?
token我们可以理解为一个令牌,主要的作用是守护我们系统的安全,像我们登录这些都是可以使用token进行用户数据校验的,那么为什么不用传统的session呢?主要还是session是前端页面生成给我们的,当某一个窗口关闭了以后或者session发生了变化那么在请求服务就歇菜了,session的主动权在与前端,而token的主动权者在于服务端。
那么我们如何实现呢?看下面的代码吧!
<!--导入下面依赖吧--> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.3.0</version> </dependency>
生成token
//设置过期时间(毫秒为单位)
private static final long EXPIRE_DATE=1*60*1000;
//token秘钥(可以自定义一个随机字符串就行,避免中文)
private static final String TOKEN_SECRET = "ZCEQIUBFKSJBFJH2020BQWE";
/**
*
* @param username 传入用户名
* @param password 传入密码
* @return
*/
@GetMapping("/getToken")
public String getToken(String username, String password) {
String token = "";
try {
//过期时间
Date date = new Date(System.currentTimeMillis() + EXPIRE_DATE);
//秘钥及加密算法
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
//设置头部信息
Map<String, Object> header = new HashMap<>();
header.put("typ", "JWT");
header.put("alg", "HS256");
//携带username,password和用户ID信息,生成签名,按照需求而定
token = JWT.create()
.withHeader(header)
.withClaim("username", username).withClaim("userId", 用户id)
.withClaim("password", password).withExpiresAt(date)
.sign(algorithm);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return token;
}
校验token是否过期
/**
* 校验Token是否过期
* @param token
* @return
*/
public static boolean verifyToken(String token){
try {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
JWTVerifier verifier = JWT.require(algorithm).build();
verifier.verify(token);
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
解析token信息
/**
* 解析Token
* @param key 需要解析的key字符串(username、userId等等,就是携带数据生成token的Key)
* @param token 传入token
* @return
*/
public static String getUsername(String token,String key){
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim(key).asString();
}catch (JWTDecodeException e){
e.printStackTrace();
}
return null;
}
可能很多人直接使用上面的代码进行登录接口实现了,那么同志们有想过一个问题吗?上面设置了token的过期时间的,当用户正在使用我们软件的时候,突然token过期了直接报了个401,这个时候用户肯定是一脸懵逼了,有很多软件都会出现这个问题,就是因为偷懒了,我们不经常发现是因为他们的token设置的过期时间较长而已。我下面给大家提供了解决方案。
1、后台可以在生成token返回给前端的时候缓存一下token,比如我们token过期时间是30分钟,那么我们缓存有效期就设置10分钟就行了,前端每次请求都刷新我们的缓存,如果前端10分钟都没有请求的话我们的token就自动过期了,如果我们的缓存token没过期但是实际token过期了怎么办呢?这个时候我们就可以直接生成一个新的token返回给前端。
2、生成token的时候生成两个token返回给前端(假如生成了A和B两个token)A的Token返回给前端用作数据交互,B的Token用来刷新A的Token,这个时候我们就可以将B设置过期时间长一点,当后台发现A过期的话返回401给前端,前端在使用B来换取新的token,我们后台收到换取token通知的时候将原来A里面的数据解析出来重新使用数据生成一个新的token返回给前端。
温馨提示一下 : 我们在生成token的时候需要注意要防止别人去里面解析数据,最好对token进行数据的加密处理。比如有的同学使用账号密码生成token,这种方法要特别注意。