Session vs Token Authentication: Understanding HTTP Statelessness and JWT Implementation in Java
This article explains how HTTP's stateless nature requires session or token mechanisms for preserving user state, compares session‑based and JWT‑based authentication, details JWT structure, and provides a complete Java implementation with code examples.
HTTP is a stateless protocol that enables communication between client and server, originally designed for web browsers and servers.
Because HTTP does not retain state, web applications must use mechanisms such as sessions or tokens to preserve user data like shopping cart contents during a browsing session.
1. Session‑based authentication
Before JWT, most applications relied on server‑side sessions. The server creates a session object, stores it in memory, and sends a session ID to the client via a cookie. The cookie is sent with each request, allowing the server to look up the stored session data and verify the user.
Session cookies without an explicit Expires or Max‑Age attribute are deleted when the browser closes, but browsers may restore them, effectively keeping the session alive.
2. Token‑based authentication
Modern RESTful APIs commonly use JSON Web Tokens (JWT). After a successful login, the server issues a signed JWT that the client stores (often in localStorage) and includes in the Authorization header of subsequent requests.
The JWT contains three Base64‑URL parts (header, payload, signature) and can be verified on each request without server‑side state, improving scalability for large numbers of users.
Typical usage pattern:
localStorage.setItem("key", "value");3. JWT implementation example (Java)
private static final long EXPIRE_TIME = 60 * 1000 * 60 * 24 * 7;
private static String ISSUER = "K_ang";
private static final String SING = "K*&^A%$#N@!G";
/** Generate token */
public static String getToken(Map<String, String> map) {
Date date = null;
try {
date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
JWTCreator.Builder builder = JWT.create()
.withIssuer(ISSUER)
.withExpiresAt(date);
map.forEach((k, v) -> {
builder.withClaim(k, v);
});
return builder.sign(Algorithm.HMAC256(SING));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/** Verify token */
public static boolean verify(String token, String userNo) {
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SING))
.withClaim("userNo", userNo).build();
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception e) {
return false;
}
}
/** Extract token info */
public static String getTokenInfo(String token) {
DecodedJWT decode = JWT.decode(token);
return decode.getClaim("userNo").asString();
}The article also invites readers to discuss the topic, share opinions, and join a community where additional resources and promotional offers are provided.
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.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.
