In short
With sessions, the server must look you up on every request. A JWT carries your identity inside a signed token, so any server can check it with just a key and no lookup.
JSON Web Tokens — a compact, signed token format that lets a stateless server verify a user's identity without looking anything up in a database on every request.

Think of it like this
A stamped admit card
At the exam hall, the invigilator doesn't phone the board to check you. Your admit card has your details and an official stamp that's hard to fake. One look and you're in. A JWT is that admit card: your details, plus a signature the server can verify on its own.
Watch it happen
Sign once, verify anywhere
POST /login
1/6You log in once with your email and password.
The big ideas
What you need to know
Three parts, dot-separated
header.payload.signature. The first two are just Base64URL-encoded JSON, so anyone can read them.
Signed, not secret
The signature stops tampering, not reading. Never put passwords or private data in the payload.
Keep them short-lived
Set exp to around 15 minutes. A JWT is hard to cancel early, so a short life limits the damage.
Pin the algorithm
Verify with a fixed algorithm like HS256 or RS256. Never trust the alg value inside the token itself.
See it in code
Walk through the code
1import { SignJWT, jwtVerify } from "jose";2const secret = new TextEncoder().encode(process.env.JWT_SECRET!);3 4export async function issueToken(userId: string) {5 return new SignJWT({ role: "student" })6 .setProtectedHeader({ alg: "HS256" })7 .setSubject(userId)8 .setIssuedAt()9 .setExpirationTime("15m")10 .sign(secret);11}12 13export async function verifyToken(token: string) {14 const { payload } = await jwtVerify(token, secret, { algorithms: ["HS256"] });15 return payload; // { sub, role, iat, exp }16}1/3The secret as bytes. Keep it long, random and out of git.
jose works in Node, Bun, Deno and edge runtimes. A route middleware would read the Bearer header and call verifyToken.
Save yourself the pain
Common mistakes
Oops
Putting the user's email, phone or password hash inside the JWT payload.
Do this instead
Anyone can Base64-decode it. Put only an id and a role, and fetch the rest from the database.
Oops
Issuing JWTs that last 30 days.
Do this instead
A stolen token works until it expires. Keep access tokens short and use refresh tokens for long logins.
Your mission
Decode your own JWT
Quick check
Your JWT payload says role: "student". Can someone read it without the secret key?
Go deeper
- 1Generate and verify a JWT manually using a library like `jsonwebtoken`.
- 2Decode a real JWT at jwt.io and inspect its header, payload and signature.
- 3Learn why JWT payloads are readable, not encrypted — never put secrets in them.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.