Why JWT May Not Be Suitable for My System and a Comparison with Token+Redis
The article explains JWT fundamentals, shows how to integrate it with SpringBoot, compares JWT with a Token‑plus‑Redis approach, and argues why using JWT alone can be problematic in a system that already relies on Redis for session management.
In this technical note the author, who previously learned the Shiro framework, shares his experience of using JWT for authentication in a SpringBoot project and why he eventually decided that JWT was not the right choice for his system.
What is JWT?
JWT (JSON Web Token) is a compact, URL‑safe means of representing claims to be transferred between two parties. It consists of three parts: Header, Payload, and Signature.
Header
The header typically contains the token type ("typ": "JWT") and the signing algorithm (e.g., "alg": "HS256").
Payload
The payload carries the claims, such as issuer, subject, expiration time, and any custom data (e.g., {"sub":"1234567890","name":"John Doe","exp":1516239022}).
Signature
The signature is created by signing the Base64Url‑encoded header and payload with a secret key, allowing the receiver to verify integrity and authenticity.
Using JWT with SpringBoot
Maven Dependency
<!-- jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.2</version>
</dependency>Code Example
import java.util.Date;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@Slf4j
public class JWTUtil {
private static final long EXPIRE_TIME = 60 * 1000;
/** Verify token */
public static boolean verify(String token, String username, String secret) {
try {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withClaim("username", username)
.build();
verifier.verify(token);
log.info("token is valid");
return true;
} catch (Exception e) {
log.info("token is invalid{}", e.getMessage());
return false;
}
}
/** Extract username from token */
public static String getUsername(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim("username").asString();
} catch (JWTDecodeException e) {
log.error("error:{}", e.getMessage());
return null;
}
}
/** Generate token */
public static String sign(String username, String secret) {
try {
username = StringUtils.lowerCase(username);
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.create()
.withClaim("username", username)
.withExpiresAt(date)
.sign(algorithm);
} catch (Exception e) {
log.error("error:{}", e);
return null;
}
}
public static void main(String[] args) {
// encrypt data
String token = sign("zhangshan", "123456");
System.out.println(token);
// decrypt data
System.out.println(getUsername(token));
}
}JWT vs. Token+Redis
When designing a stateless system, two common options are using pure JWT or a Token stored in Redis.
Principles
JWT: The token is self‑contained; the server does not store it. Validation relies on signature and expiration. However, the server cannot revoke a JWT before it expires.
Token+Redis: A short random key is stored in Redis with user data. The server can delete the key at any time, enabling immediate revocation.
Pros and Cons
Decentralized JWT
Advantages: Easy to use in distributed systems; can embed basic user info (username, roles) directly.
Disadvantage: Server cannot actively invalidate a token.
Centralized Redis+Token
Advantage: Server can force token invalidation.
Disadvantages: Requires Redis (memory) and adds complexity in distributed environments.
My Proposed Solution
The author combines both approaches: JWT + Redis. After generating a JWT, it is encrypted and stored in Redis, allowing revocation while retaining the JWT format. This adds an extra encryption step, which the author admits makes the token longer and the process more cumbersome.
Why JWT Feels Awkward in This Context
Extra encryption defeats JWT’s built‑in expiration handling, forcing reliance on Redis for expiry.
Frequent admin operations (adding/removing permissions) expose the inability of JWT to be revoked promptly.
As the system evolves, JWT strings become very long, consuming bandwidth.
Single sign‑on/logout cannot be cleanly achieved with pure JWT.
Conclusion
The author concludes that while JWT is simple and popular, it is not a universal solution; choosing the right authentication mechanism depends on the specific requirements of the system. In many cases, a hybrid JWT+Redis approach or a plain Redis‑based token may be more appropriate.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
