Information Security 11 min read

Automatic JWT Token Renewal to Prevent User Re‑Login

This article explains how to automatically renew JWT tokens in a front‑end/back‑end separated system by storing tokens in a cache, checking them in a filter, and refreshing them when expired, thereby preventing frequent logins and preserving form data.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Automatic JWT Token Renewal to Prevent User Re‑Login

Introduction

In a front‑end/back‑end separated architecture, after a successful login the back‑end issues a JWT token that the front‑end (e.g., Vue) stores in LocalStorage. Subsequent requests send this token in the request header, where a back‑end filter validates its expiration and redirects to login if it is invalid.

Because JWT tokens usually contain basic user information, their expiration time is set short for security, which can cause frequent logins, especially when users spend a long time filling complex forms.

This article demonstrates how to automatically renew the token without user awareness, avoiding repeated logins and loss of form data.

Implementation Principle

The automatic renewal works as follows:

After login, store the generated JWT token as both key and value in a cache (e.g., Redis) with an expiration time twice the token’s lifetime.

For each request, a JWT filter checks the token from the request header. If the token is invalid, an exception is thrown.

The filter retrieves the cached token and handles three cases: If the cached token does not exist, the user session is considered timed out and a re‑login is required. If the cached token exists and is still valid, no action is needed. If the cached token exists but is expired, the back‑end generates a new JWT token, overwrites the cache value, and resets the cache expiration.

Core principle: The token sent in the request header remains unchanged; its validity is determined by the token stored in the cache.

Code Implementation (Pseudo‑code)

Issue token after successful login and set its expiration.

...
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 and set the Redis expiration to twice the token’s lifetime.

Sting tokenKey =
"sys:user:token"
+ token;
redisUtil.set(tokenKey, token);
redisUtil.expire(tokenKey,
30
*
60
*
2
);

Filter validates the token’s validity.

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!"
)
}
...
}

Automatic token renewal logic.

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
;
}
}

The JWT operations rely on com.auth0.java-jwt and the custom JwtUtil utility class.

Conclusion

The essential idea is that the token in the request header stays unchanged, while its validity is verified against the cached token; never validate the header token directly. Understanding the principle is more important than the concrete code.

backendJavaRedisauthenticationJWTToken Renewal
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.