On this page
What you need first
This lesson uses ideas from these earlier lessons. Read them first if any idea is new to you.
01Why interviewers ask this
Almost every design has a login. The interviewer asks: "How does the server know who is calling?" Then comes the harder question: "A user's phone is stolen. How do you block it?"
A weak answer is "we use a token" or "we use cookies", with no reason. A strong answer says where the proof of login is kept, how long it lasts, and how you cancel it early. It also shows what each choice costs.
At SDE-1 level you should explain a session and a token. At SDE-2 level you should explain expiry and the cancel problem, with numbers. At SDE-3 level you should also say what breaks when server clocks differ, and which risk you accept.
02The idea in plain words
Think of a college campus with many gates. There are two ways to let students in.
Way 1. At the first gate, the guard checks your ID card and gives you a numbered token. The guard writes your number and name in a register that every gate can read. At each gate, the guard looks up your number. If you lose the token, the guard crosses out the number, and it stops working at once. But every entry needs a look in the register.
Way 2. At the first gate, the guard gives you a card. It has your name and an end date, and a seal that is hard to copy. Each gate checks the seal and the date. There is no register, so entry is fast. But if you lose the card, no gate can cancel it. It works until the end date.
Way 1 is a session. Way 2 is a token.
Login and the proof
Authentication means proving who you are. Login is the first proof. HTTP forgets you between requests (lesson 7), so each next request must carry proof again. If the proof is missing or wrong, the API answers 401 (lesson 9).
The server must never store your password. It stores a hash: a one-way scramble. You can make a hash from a password, but you cannot get the password back from the hash. At login, the server hashes what you typed and compares. Use a library and a slow hash made for passwords, such as Argon2id or bcrypt.
Sessions: the proof stays on the server
After a good login, the server makes a session ID: a long random code. It must be hard to guess, so use at least 64 bits of randomness. The server saves a session record (user ID, start time, end time) in a shared store, as in lesson 26. It sends the ID to the browser in a cookie. On each request, the server reads the ID from the cookie and looks up the record. No record means 401.
The cookie has settings, defined in RFC 6265 (an internet standard):
Secure: the browser sends the cookie only over HTTPS.HttpOnly: scripts that run in the page cannot read the cookie.Max-Age: the life of the cookie, in seconds.
Make a new session ID right after login, so that an ID known before login is useless.
A session has two time limits. The idle timeout ends it after some time with no requests. The absolute timeout ends it after a fixed total time, even if the user is active. OWASP, a non-profit group that publishes free security guides, says common idle timeouts are 15 to 30 minutes for low-risk apps and 2 to 5 minutes for high-value apps. For an office app used all day, it says 4 to 8 hours is a suitable absolute timeout.
To log out, or to block a stolen session, delete the record. The next request fails. Clearing the cookie in the browser is not enough, because the ID still works until the server deletes the record.
Tokens: the proof travels with the request
A JSON Web Token (JWT) has three parts joined by dots: header, payload and signature. Each part is written in base64url, a way to write bytes as plain letters and digits. The header names the signing method. The payload holds claims: named facts. The signature is a code made from the header, the payload and a secret key (this is the common shared-secret method). It is the same idea as the pre-signed URL of lesson 24. A typical payload:
{"sub":"u_42","iat":1792506600,"exp":1792507500}sub is the user ID. iat is the time of issue. exp is the time after which the token must be refused. Times are in Unix time: the number of seconds since 1 January 1970. Here exp minus iat is 1,792,507,500 - 1,792,506,600 = 900 seconds = 15 minutes. A token can also have nbf ("not before"), a time before which it must be refused.
To check a token, the server makes the signature again with the secret key. If the codes are equal and the time is before exp, the token is good. There is no lookup, so any server with the key can check it. Three rules:
- A JWT is signed, not encrypted. Anyone can decode the payload and read it. Put no secrets in it.
- Always check the signature. Name the allowed signing method in your code, and refuse a token that says its method is
none(RFC 8725, the security advice for JWT). - Keep the token in an
HttpOnlycookie, so page scripts cannot read it. This is design advice, not part of the JWT standard.
Expiry and the clock
The server checks exp with its own clock. Clocks differ (lesson 49). A server whose clock is 20 minutes ahead sees every new 15-minute token as already expired. A server whose clock is 2 minutes behind may see a token with nbf as "not valid yet". The JWT standard lets a server allow a small leeway, "usually no more than a few minutes". A leeway (a small extra time) of 30 to 60 seconds hides small differences. It cannot hide big ones. The real fix is to keep every clock correct.
The cancel problem
To revoke a login is to cancel it before its normal end: at logout, after a theft, or when an admin blocks a user. A session needs one delete. A JWT has nothing to delete, because every server can check it alone. It stays valid until exp. There are three fixes:
- A short access token and a refresh token. The access token lives 15 minutes. A refresh token is a long random code that the server stores, like a session ID. When the access token ends, the app sends the refresh token. The server checks its record and gives a new access token. To revoke, delete the refresh record. A stolen access token then dies within 15 minutes.
- A denylist. Keep a list of revoked token IDs (the
jticlaim, a unique ID in each token) until they expire. Each request checks the list. The list stays small, because an entry can leave when itsexppasses. But state is back, and every check needs it. - Use sessions.
| Question | Session | JWT |
|---|---|---|
| Where is the proof? | In the server store. The cookie holds an ID. | In the token |
| Cost of a check | One lookup | A signature check, no lookup |
| Cancel now? | Yes, delete the record | No, wait for exp (or use a denylist) |
| Bytes per request (sizes assumed below) | The ID, 32 bytes | The token, about 300 bytes |
Stuck on something? The AI tutor has read this lesson. Ask it with a free account
03Pause and predict
Pause. Guess first.
A user's phone is stolen. The user taps "log out everywhere". How soon is the thief blocked if the login is a session record in a shared store? How long can the thief use the phone if the login is a 15-minute JWT and nothing else changes?
Write your guess before you read on. The answer is in the worked example.
04Worked example
We use the food-ordering app of lesson 3, with the numbers of lesson 26.
Assumptions (made up to teach with):
- 500,000 users are logged in at the peak, and the peak is 20,000 requests per second.
- The shared store does 100,000 operations per second. A session record is 1 KB. A lookup adds 0.5 ms.
- A session ID is 16 random bytes written as 32 characters, so the cookie adds 32 bytes.
- A token is 300 bytes and lives 900 seconds (15 minutes). Checking a signature takes 0.05 ms of CPU.
- A refresh token lives 30 days. There are 12 API servers, and requests are shared evenly.
Step 1: sessions.
- Lookups: 20,000 per second, which is 20,000 / 100,000 = 20% of the store.
- Memory: 500,000 x 1 KB = 500 MB.
- Extra data: 20,000 x 32 bytes = 640,000 bytes per second, which is 0.64 MB, or 5.1 megabits per second.
Step 2: tokens.
- Lookups: none.
- Extra data: 20,000 x 300 bytes = 6,000,000 bytes per second = 6 MB = 48 megabits per second. That is 300 / 32 = 9.4 times more than the session ID.
- CPU: 20,000 x 0.05 ms = 1,000 ms of work per second, which is one core.
Step 3: the stolen phone. With a session, the delete takes effect on the thief's next request, which gets 401. With the token, the thief can use it until exp: at most 900 seconds, which is 15 minutes. This answers the predict box. If the token lived 24 hours, the window would be 24 x 60 / 15 = 96 times longer.
Step 4: add a refresh token. Each of the 500,000 users asks for a new access token every 900 seconds. That is 500,000 / 900 = 556 lookups per second (rounded from 555.6). It is 556 / 20,000 = 2.8% of the lookups of the session design. To block the user, delete the refresh record. The thief's window is at most 15 minutes, and not 30 days.
Step 5: one wrong clock. One of the 12 servers runs 20 minutes ahead. A new token has exp = issue time + 15 minutes. That server reads issue time + 20 minutes, so it refuses every token. A leeway of 60 seconds does not help, because 20 minutes = 1,200 seconds is more than 900 + 60. So 1 / 12 = 8.3% of requests get 401, and a retry often works because it lands on another server. Group the failures by server to find the cause.
05Trade-offs
- Sessions solve instant cancel: one delete. They cost one lookup per request (20% of the store here, and 0.5 ms), and a store that must stay up. I would use them for a normal website. I would change when many separate services must check logins without calling one store.
- A JWT solves a check with no lookup, by any server that has the key. It costs no cancel before
exp, about 9 times more bytes per request than a session ID, and a payload that anyone can read. I would change to a session if I must block users at once. - A short token with a refresh token solves most of the cancel problem. It costs a stored record again (556 lookups per second here) and more code. I would change the 15 minutes to a shorter time if a stolen token costs a lot.
06Common misconceptions
"A JWT is encrypted, so I can put the user's phone number and role in it." A JWT is signed, not encrypted. The payload is only base64url text, and anyone can decode it. The signature stops changes. It does not hide anything.
"JWT is stateless, so it is always better than sessions." The check is stateless, but cancelling is not. To block a user at once, you need state again: a refresh record or a denylist. Session lookups used 20% of one store at 20,000 requests per second, which is small.
"Logout deletes the token, so the user is logged out." Deleting the token on the phone removes only that copy. A copy that someone else holds stays valid until exp. To log out for real, delete the server record: the session, or the refresh token.
07How to say it in the interview
Say it like this
I keep a random session ID in a Secure, HttpOnly cookie and the record in a shared store, so a logout is one delete. With a signed 15-minute token and a stored refresh token, servers check logins without a lookup, and a stolen token works 15 minutes at most.
08Check your understanding
- What are the three parts of a JWT? Why must you put no secret in it? What does a server do to check one?
- Peak load is 30,000 requests per second. The store does 100,000 operations per second. A session ID is 32 bytes and a token is 300 bytes. (a) What share of the store do session lookups use? (b) How much more data per second do tokens add than session IDs, in megabits? (c) With 600,000 users and a 15-minute access token, how many refresh lookups per second?
- A team uses 24-hour tokens. After a hacked account is reported, support blocks the user, but the attacker still reads orders for hours. Why? What do you change?
09Answers
Show the answers
- Header, payload and signature. The payload is only encoded, so anyone can read it. The server makes the signature again with its secret key, compares it, and checks that the time is before
exp. - (a) 30,000 / 100,000 = 30%. (b) Tokens: 30,000 x 300 = 9,000,000 bytes per second = 72 megabits. Session IDs: 30,000 x 32 = 960,000 bytes per second = 7.7 megabits. The difference is about 64.3 megabits per second. (c) 15 minutes = 900 seconds. 600,000 / 900 = 667 lookups per second.
- A token is valid until
exp, and the servers do not ask anyone, so blocking the user changes nothing for 24 hours. Use an access token of about 15 minutes and a stored refresh token. Support deletes the refresh record. A denylist of token IDs also works. The window falls from 24 hours to 15 minutes, which is 96 times less.
10Sources
- JWT parts, claims
exp,nbf,iat,suband the leeway of "a few minutes" for clock skew: RFC 7519, https://www.rfc-editor.org/rfc/rfc7519.html (opens in a new tab) (checked 20 Oct 2026). A signed JWT gives integrity, not secrecy. - Refuse the
nonemethod unless you ask for it: RFC 8725 section 3.2, https://www.rfc-editor.org/rfc/rfc8725.html (opens in a new tab) (checked 20 Oct 2026). - Cookie settings
Secure,HttpOnly,Max-Age: RFC 6265, https://www.rfc-editor.org/rfc/rfc6265.html (opens in a new tab) (checked 20 Oct 2026). - Session ID of at least 64 bits, new ID after login, idle and absolute timeouts and their ranges, server-side invalidation: OWASP Session Management Cheat Sheet, https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html (opens in a new tab) (checked 20 Oct 2026).
- Denylist of token IDs (
jti) and short lifetimes: OWASP JSON Web Token Cheat Sheet, https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_Cheat_Sheet.html (opens in a new tab) (checked 20 Oct 2026). - Argon2id and bcrypt for passwords: OWASP Password Storage Cheat Sheet, https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html (opens in a new tab) (checked 20 Oct 2026).
- The user counts, request rates, store speed, sizes, signature time and the 30-day refresh life are assumptions made for teaching. The token time stamps are calculated for 20 October 2026, 20:00 in India. Keeping the token in an
HttpOnlycookie is design advice, not a rule of a standard.
Try it now, no sign-up
- Play Level 1: one server and 100 users. Free, no sign-up.
- Read today’s Drill: one real situation, answered in about 7 minutes.
More practice, in the app (free account)
Related lessons and practice
Ask the AI tutor about this lesson
The tutor has read this lesson. Ask in your own words, any time. Free account, 20 questions a day.
Reading never needs an account. The account is for the tutor, the quiz, your notes and your progress.