Let's Talk About JWT
March 19, 2026
JWT (JSON Web Token) is a compact, signed string your browser sends with each request after you sign in, so my API knows who you are.
What’s inside
A JWT has three parts (header, payload, signature), Base64-encoded. The payload holds claims such as who you are and when the token expires. The signature proves the token wasn’t tampered with, as long as the server’s secret stays private.
How JWT works
Here's the detailed breakdown of the JWT flow:
1. User authentication — You provide your credentials (email and password or Google OAuth) to the authorization server.
2. Credential verification — I validate the credentials against my database.
3. Token generation — Upon successful verification, I generate a JWT that encodes who you are and when it expires, then return it to the client. My Spring service builds it like this:
fun generateToken(extraClaims: Map<String, Any>, userDetails: UserDetails): String {
return Jwts.builder()
.claims(extraClaims)
.subject(userDetails.username)
.issuedAt(Date())
.expiration(Date(System.currentTimeMillis() + expiration))
.signWith(getSigningKey())
.compact()
}4. Token transmission — I send the JWT token to your browser, typically in the response body or as a cookie.
5. Client storage — Your browser stores the JWT token in the local storage or session storage.
6. Authenticated Requests — For subsequent requests, the client includes the JWT in the Authorization header.
7. Token validation — I validate the token and extract the information about you.
After parsing and verifying the signature, I ensure the token's subject matches the current user and that it has not expired:
fun isTokenValid(token: String, userDetails: UserDetails): Boolean {
val username = extractUsername(token)
return username == userDetails.username && !isTokenExpired(token)
}8. Request processing — If valid, I process your request and return the response.