Preface
In the development mode where the front and back ends are separated, the back-end service will issue a jwt token to the user after the front-end user logs in successfully. The front end (such as vue) will store the token in LocalStorage after receiving the jwt token.
Each subsequent request will put this token in the request header and pass it to the back-end service. The back-end service will have a filter to intercept the token and verify whether the token has expired. If the token expires, the front-end will be redirected to Log in to the login page again.
Because the jwt token generally contains the user's basic information, in order to ensure the security of the token, the expiration time of the token is generally set to be relatively short.
However, this will cause the front-end users to log in frequently (the token expires), and some forms are even more complicated. The front-end users need to think for a long time when filling in the form. When the form is submitted, the back-end verification finds that the token has expired. Jump to the login page.
If this happens, the front-end users will definitely curse, and the user experience is very unfriendly. The content of this article is to realize the automatic renewal of the token without the front-end user's perception, so as to avoid frequent logins and loss of form filling content.
Implementation principle
The realization principle of jwt token automatic renewal is as follows:
-
After a successful login a user-generated
jwt token
as a key, value stored in the cache buffer inside (this time the key, the same value value), the cache is valid to 2 times the token valid time. -
When the user request again, through a rear end of the
jwt Filter
check front end token is a valid token, if the front end token invalid indicate that the request is illegal, it can be directly thrown; -
Take out the cache token according to the rules, and judge whether the cache token exists. At this time, there are mainly the following situations:
-
Cache token does not exist.
This situation indicates that the user account has timed out and the returned user information is invalid. Please log in again. -
If the cache token exists, you need to use the jwt tool class to verify whether the cache token has expired . If it does not expire , no processing is required.
Expiration means that the user has been operating but the token is invalid. The back-end program will regenerate the jwt token for the value value mapped by the key corresponding to the token and overwrite the value value. The cache life cycle is recalculated.
The core principle of the implementation logic: the token set in the front-end request header remains unchanged, and the validity of the verification is subject to the token in the cache.
Code implementation (pseudo code)
-
After successful login, the token will be issued to the user and the validity period of the token will be set
...
SysUser sysUser = userService.getUser(username,password);
if(null !== sysUser){
String token = JwtUtil.sign(sysUser.getUsername(),
sysUser.getPassword());
}
...
public static String sign(String username, String secret) {
//设置token有效期为30分钟
Date date = new Date(System.currentTimeMillis() + 30 * 60 * 1000);
//使用HS256生成token,密钥则是用户的密码
Algorithm algorithm = Algorithm.HMAC256(secret);
// 附带username信息
return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
}
-
Store the token in redis, set the expiration time, and set the expiration time of redis to twice the expiration time of the token
Sting tokenKey = "sys:user:token" + token;
redisUtil.set(tokenKey, token);
redisUtil.expire(tokenKey, 30 * 60 * 2);
-
The filter verifies the token and verifies the validity of the token
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
//从header中获取token
String token = httpServletRequest.getHeader("token")
if(null == token){
throw new RuntimeException("illegal request,token is necessary!")
}
//解析token获取用户名
String username = JwtUtil.getUsername(token);
//根据用户名获取用户实体,在实际开发中从redis取
User user = userService.findByUser(username);
if(null == user){
throw new RuntimeException("illegal request,token is Invalid!")
}
//校验token是否失效,自动续期
if(!refreshToken(token,username,user.getPassword())){
throw new RuntimeException("illegal request,token is expired!")
}
...
}
-
Realize automatic renewal of token
public boolean refreshToken(String token, String userName, String passWord) {
Sting tokenKey = "sys:user:token" + token ;
String cacheToken = String.valueOf(redisUtil.get(tokenKey));
if (StringUtils.isNotEmpty(cacheToken)) {
// 校验token有效性,注意需要校验的是缓存中的token
if (!JwtUtil.verify(cacheToken, userName, passWord)) {
String newToken = JwtUtil.sign(userName, passWord);
// 设置超时时间
redisUtil.set(tokenKey, newToken) ;
redisUtil.expire(tokenKey, 30 * 60 * 2);
}
return true;
}
return false;
}
...
public static boolean verify(String token, String username, String secret) {
try {
// 根据密码生成JWT效验器
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
// 效验TOKEN
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception exception) {
return false;
}
}
Jwt article related operations are based on com.auth0.java-jwt
realization, you can get by reading the original JwtUtil
tools.
summary
jwt token implement the core principles of logic is the token request Header set in front-end remains unchanged, to verify the effectiveness of the cache token prevail, do not directly check Header in the token . In the realization principle part, everyone has a good experience, thinking is more important than realization!
If this article is helpful to you, don't forget to give me three links: like, forward, and comment. See you next time!
Favorite equal to the white prostitute , thumbs up is the truth!
Here is a small gift for everyone, follow the official account, enter the following code, you can get the Baidu network disk address, no routines!
001: "A must-read book for programmers"
002: "Building back-end service architecture and operation and maintenance architecture for small and medium-sized Internet companies from scratch"
003: "High Concurrency Solutions for Internet Enterprises"
004: "Internet Architecture Teaching Video"
006: " SpringBoot Realization of
Ordering System" 007: "SpringSecurity actual combat video"
008: "Hadoop actual combat teaching video"
009: "Tencent 2019 Techo Developer Conference PPT"
010: WeChat exchange group