HTTP & API JWT Interview Questions
Reviewed by Mark Dickie · Last updated
JSON Web Tokens (JWTs) are compact, URL-safe tokens that carry signed claims between two parties, most often a client and an API server. For an interview on API authentication you should know the three-part token structure (header, payload, signature), the difference between signing algorithms like HS256 and RS256, how expiry and refresh tokens fit into a session lifecycle, and the security mistakes that make JWT implementations fail in production.
A JWT is encoded as three Base64URL segments joined by dots: header.payload.signature. The header identifies the algorithm, the payload carries claims such as sub, exp, and iat, and the signature lets the server verify that the token was not tampered with. The server does not need a database lookup on every request — it validates the signature and reads the claims directly. That statelessness is the main reason teams pick JWT for distributed API architectures.
What does a JWT interview question typically test?
Interviewers focus on whether you understand what the token guarantees and where those guarantees stop. The signature proves integrity and origin, not confidentiality — the payload is Base64URL-encoded, not encrypted. If you need to hide claim values, you must wrap the token in TLS or use a JWE (encrypted) variant.
| Topic | What to know |
|---|---|
| Token structure | Header, payload, signature — Base64URL-encoded, joined by dots |
| Signing algorithms | HS256 (shared secret) vs RS256 / ES256 (asymmetric key pair) |
| Claims | iss, sub, aud, exp, iat, nbf — what each one means |
| Expiry strategy | Short-lived access tokens paired with longer-lived refresh tokens |
| Storage on client | httpOnly cookies vs localStorage — XSS vs CSRF trade-offs |
| Revocation | Token blacklists, short exp, rotating signing keys |
How should you handle token expiry and refresh?
A common pattern is to issue an access token with a 5–15 minute lifetime and a refresh token that lasts days or weeks. The client sends the access token in the Authorization: Bearer header; when it expires, the client calls a refresh endpoint to get a new one without forcing the user to log in again.
-
Server signs the access token with
expset to a short window and returns it alongside a refresh token. -
Client stores the tokens and sends the access token on each API request via the
Authorizationheader. -
When the access token expires, the client posts the refresh token to a dedicated endpoint to receive a fresh access token.
-
Server validates the refresh token (often stored server-side or bound to a session) and issues a new access token.
-
If the refresh token is invalid or revoked, the client redirects the user to re-authenticate.
What are the most common JWT security mistakes?
Accepting alg: none is the classic one — if your library does not reject unsigned tokens, an attacker can strip the signature and forge any payload. Other frequent failures: storing tokens in localStorage where XSS can exfiltrate them, using HS256 with a weak or shared secret across services, and never rotating signing keys. Know these cold before the interview, because they come up in nearly every JWT question.
Key facts
- Tarmac has 26 HTTP & APIs interview questions on this topic, 10 of them on this page, at difficulty 2–5 of 5.
- Tarmac tracked 4,906 job postings asking for HTTP & APIs in August 2026.
- Roles asking for HTTP & APIs advertise a median base salary of US$167,500, across 883 job postings as of August 2026.
- Tarmac last reviewed these HTTP & APIs interview questions on 14 September 2026.
At a glance
| Questions | 10 shown · 26 in the bank |
|---|---|
| Difficulty | 2–5 of 5 |
| Formats | Multiple choice, Find the bug, Fill in the blank, True / false, Short answer, Multiple answer |
What you'll review
- api auth
- jwt
Practice questions
Try one before you open the answer. Pick an option and press Check; it's marked on the spot.
HTTP & APIs/api-auth
A single-page application (SPA) running in the browser needs to obtain an OAuth 2.0 access token to call a backend API on behalf of a signed-in user. The SPA cannot securely store a client secret. Which OAuth 2.0 flow is the current recommended approach for this scenario?#
Options
Show answer
Use the Authorization Code flow with PKCE. It is the current OAuth 2.0 Security BCP recommendation for public clients like SPAs that cannot store a client secret. PKCE replaces the static secret with a per-request code challenge/verifier pair, blocking authorization-code interception attacks. The Implicit grant is deprecated, Password Credentials is deprecated, and Client Credentials is for machine-to-machine, not user-delegated, access.
The Authorization Code flow with PKCE is the current OAuth 2.0 Security Best Current Practice (RFC 9700) recommendation for SPAs, native apps, and other public clients that cannot keep a client secret confidential. PKCE replaces the client secret with a dynamically generated code verifier/challenge pair, preventing an attacker from intercepting the authorization code and exchanging it for a token. The Implicit grant is deprecated because it exposes tokens in the URL fragment and offers no client authentication. The Resource Owner Password Credentials grant is deprecated because it requires the app to handle user passwords directly. The Client Credentials grant is for machine-to-machine communication where the client is acting on its own behalf, not on behalf of a user.
HTTP & APIs/api-auth
The following Python function is supposed to extract a Bearer token from the incoming HTTP request, but it always returns None even when the client sends a valid Authorization: Bearer <token> header. Which line contains the bug?#
def extract_bearer_token(request):
auth = request.headers.get("Authentication")
if auth and auth.startswith("Bearer "):
return auth[7:]
return NoneShow answer
The bug is on line 2.
Line 2 reads the header named "Authentication", but the standard HTTP header for bearer credentials is Authorization. Since no Authentication header is sent, auth is None, the if guard fails, and the function returns None. Changing the header name to "Authorization" fixes the extraction.
HTTP & APIs/api-auth
When sending an OAuth 2.0 Bearer access token in an HTTP request, the token is placed in the _____ request header using the scheme Bearer <token>. According to RFC 6750, this header name is case-insensitive but the scheme name (Bearer) is case-sensitive and must be followed by exactly one space and the token value.#
Show answer
When sending an OAuth 2.0 Bearer access token in an HTTP request, the token is placed in the **Authorization** request header using the scheme Bearer <token>. According to RFC 6750, this header name is case-insensitive but the scheme name (Bearer) is case-sensitive and must be followed by exactly one space and the token value.
RFC 6750 defines the standard method for transmitting OAuth 2.0 bearer tokens: the client places the access token in the Authorization header using the Bearer authentication scheme, formatted as Authorization: Bearer <access_token>. While HTTP header names are case-insensitive per RFC 7230, the Bearer scheme name itself is case-sensitive per RFC 6750. This is the preferred and most secure of the three methods defined in RFC 6750 (the others being URI query parameter and form-encoded body parameter, both of which have security drawbacks such as logging exposure).
HTTP & APIs/api-auth
In a signed JSON Web Token (JWT), the middle segment (the payload, between the two periods) is cryptographically encrypted, so an attacker who intercepts the token cannot read its claims.#
Options
Show answer
False. A signed JWT's payload is only Base64URL-encoded, not encrypted. Anyone who intercepts the token can decode it and read every claim. The signature provides integrity (proof of issuer and tamper resistance) but not confidentiality. To hide claim contents you need an encrypted JWT (JWE), a separate standard from the signed JWT (JWS) used by most OAuth 2.0 access tokens.
A signed JWT (JWS) has three Base64URL-encoded segments: header, payload, and signature. The payload segment is only Base64URL-encoded, NOT encrypted. Anyone who obtains the token can Base64URL-decode the payload and read all claims such as sub, exp, and roles. The signature segment only provides integrity — it proves the token was issued by someone holding the signing key and was not tampered with. To keep claims confidential, you must use an encrypted JWT (JWE), which is a different and separate specification (RFC 8317) from a signed JWT (JWS, RFC 7515). Most OAuth 2.0 access tokens formatted as JWTs are JWS, not JWE, so their payloads are readable by design.
HTTP & APIs/api-auth/jwt
What does the signature of a standard (signed) JWT actually protect?#
Options
Show answer
The signature verifies integrity and authenticity — that the token was issued by the holder of the signing key and has not been tampered with. A signed JWT is not encrypted: its header and payload are only Base64URL-encoded, so anyone can decode and read the claims. For confidentiality you need JWE, and to prevent replay you rely on exp, jti, and TLS.
A signed JWS-format JWT is not encrypted — the header and payload are only Base64URL-encoded and anyone can decode and read the claims. The signature proves integrity and authenticity: that a party holding the signing key produced it and nobody altered it. It does not provide confidentiality (use JWE for that) and does not by itself prevent replay (use exp, jti, and TLS).
HTTP & APIs/api-auth/jwt
Describe the three parts of a signed JWT and what the signature gives you.#
Show answer
A JWT has three Base64URL-encoded parts separated by dots: a header (algorithm and token type), a payload of claims (such as sub, exp, and custom data), and a signature. The signature is computed over the header and payload with a secret or private key, so the server can verify the token's integrity and authenticity without a database lookup. The payload is only encoded, not encrypted, so it must never hold secrets.
JWT = header.payload.signature, each Base64URL-encoded. The signature provides integrity and authenticity (not confidentiality — a signed JWT is readable by anyone). Self-contained claims like exp let servers validate tokens statelessly, but also mean a token can't be revoked before it expires without extra infrastructure (a denylist or short lifetimes plus refresh tokens).
HTTP & APIs/api-auth
Your service verifies incoming JWTs by checking the cryptographic signature and rejects the request if it fails. A penetration test shows it will still accept a token that is well-formed, correctly signed by your own key, but was issued for a completely different downstream service and expired ten minutes ago. What is missing from the verification?#
Options
Show answer
The missing step is validating the registered claims — exp, and where present nbf, iss, and aud — not just the signature. A valid signature only proves the token was issued by the key holder and hasn't been tampered with; it says nothing about whether the token is still within its validity window or intended for this service. RFC 7519 requires checking exp (with a small clock-skew allowance), nbf, that iss matches the expected issuer, and that this service is named in aud. A larger key size or a different signing algorithm would not have caught an expired, wrong-audience token.
A signature only proves the token was issued by the holder of the signing key and hasn't been tampered with (RFC 7519 §4.1) — it says nothing about whether the token is still within its validity window or intended for this service. Verification must also check exp (MUST NOT be accepted at or after this time, with a small clock-skew tolerance permitted), nbf if present, that iss matches the expected issuer, and that aud names this service — RFC 7519 says a recipient not identified in aud should reject the JWT. Skipping this is exactly how the prompt's bug happens: a legitimately-issued token for a different service gets replayed here, or an expired token close to real time keeps being honored. (c) and (d) touch signing-algorithm strength, not claims validation, and neither would have caught an expired, wrong-audience token.
HTTP & APIs/api-auth
Your API authenticates state-changing requests (e.g. POST /transfer) using a session cookie the browser sends automatically. Select all of the following that are genuine, effective mitigations against CSRF for this design.#
Options
Pick every one that applies.
Show answer
SameSite=Strict/Lax and a per-session CSRF token are genuine CSRF mitigations; HttpOnly and JWT key rotation are not. CSRF works because browsers attach cookies automatically to any request to the target origin regardless of which page triggered it. SameSite withholds the cookie on the cross-site requests it covers, and a CSRF token is unpredictable and unreadable by the attacker's page, so a forged request is missing it. HttpOnly only stops JavaScript from reading the cookie — an XSS defense — and does nothing to stop the browser's automatic cross-site attachment, so it does not stop CSRF. Signing-key rotation is unrelated to cookie-based CSRF exposure.
CSRF exploits the fact that browsers attach cookies automatically to any request to the target origin, regardless of which page triggered it. SameSite=Strict/Lax (a) directly targets that: the browser withholds the cookie on the cross-site requests each setting covers, so a forged cross-site POST from an attacker's page arrives with no session cookie at all. A CSRF token (b) works differently but is equally effective: the attacker's page can't read or set a value it never received — the same-origin policy blocks reading responses, and a synchronizer or signed double-submit token is unpredictable and bound to the user's session — so a forged request is missing it or carries the wrong one and gets rejected. HttpOnly (c) is a real, valuable defense but against a different threat: it stops injected JavaScript (XSS) from reading and exfiltrating the cookie. It does nothing to stop the browser's normal, automatic attachment of the cookie to a cross-site request, which is the entire CSRF mechanism, so relying on HttpOnly alone leaves CSRF wide open. Rotating a JWT signing key (d) is unrelated to cookie-based session auth's CSRF exposure entirely — it limits the blast radius of a compromised key, not forged requests riding a legitimately ambient cookie.
HTTP & APIs/api-auth
Explain how PKCE works mechanically (code_verifier and code_challenge), and specifically what class of attack it defends against, and for which kind of OAuth client.#
Show answer
PKCE protects public clients — apps like SPAs and native/mobile apps that can't safely hold a client_secret — against authorization code interception. Before redirecting the user to the authorization server, the client generates a random code_verifier and derives a code_challenge from it (typically SHA-256, method S256), sending the challenge along with the authorization request. The authorization server stores the challenge against the code it issues. When the client later calls the token endpoint to exchange the code for tokens, it must also send the original code_verifier; the server re-derives the challenge from it and only issues tokens if it matches what was stored. An attacker who intercepts just the redirect-borne authorization code doesn't have the verifier — which never left the legitimate client until the token request — so they can't complete the exchange even with a valid code in hand.
PKCE (RFC 7636) exists because OAuth 2.0 public clients using the authorization code grant are "susceptible to the authorization code interception attack" — without a client secret to prove identity at the token endpoint, anyone who intercepts the code can redeem it. The verifier/challenge pair acts as a one-time, client-generated substitute for a secret: the challenge (sent up front) is a one-way function of the verifier (sent only at the end), so binding the code to the challenge lets the token endpoint confirm the same client that started the flow is the one finishing it, without ever transmitting a reusable shared secret. This matters most for mobile/native apps, where OS-level redirect interception is a real risk, and for SPAs, whose JS is fully inspectable so no secret is truly private — current OAuth security guidance recommends PKCE for all authorization-code clients, confidential or public, as defense in depth.
HTTP & APIs/api-auth
This server-side JWT verification function has a critical flaw that lets an attacker forge a token that passes verification without ever knowing the server's private signing key. Which line is responsible?#
1| function verifyToken(token, publicKey) {
2| const [headerB64, payloadB64, signatureB64] = token.split(".");
3| const header = JSON.parse(base64UrlDecode(headerB64));
4| const payload = JSON.parse(base64UrlDecode(payloadB64));
5| const signedData = headerB64 + "." + payloadB64;
6| const valid = crypto.verify(header.alg, signedData, signatureB64, publicKey);
7| if (!valid) throw new Error("invalid signature");
8| return payload;
9| }Options
Show answer
Line 6 — it verifies using the algorithm named in the token's own header instead of a fixed algorithm the server expects
The function lets the token itself dictate which algorithm verifies it (header.alg) instead of the server hardcoding the one algorithm it actually issues tokens with. This is the classic JWT "algorithm confusion" flaw: if the server expects asymmetric RS256 (signed with a private key, verified with a public key) but the verification code will run whatever crypto.verify supports for header.alg, an attacker can set alg to HS256 (a symmetric HMAC algorithm) and sign the token using the server's own public key as the HMAC secret — which is, by definition, not secret at all, since it's meant to be shared. Many JWT libraries' generic "verify with whatever alg is in the header" entry point makes this mistake easy to write; some implementations go further and also accept alg: "none", which has no signature at all, so any payload is accepted outright. The fix is to never let the token choose its own verification algorithm: pin the expected algorithm (e.g. always verify as RS256 with the known public key) at the call site, and reject any token whose header doesn't match. (b) parsing before verifying is standard practice (you need the header to know things like kid) and by itself introduces no forgery path. (c) an error message describing only "invalid signature" leaks essentially no attacker-useful information — a real but minor hardening nitpick, not what enables forgery. (d) a malformed token would just throw during parsing before reaching a security-relevant check — a crash on bad input is a different bug class from accepting a forged-but-well-formed token as valid.
Sources
The official documentation these questions are checked against:
Related interview questions
Job market
See http-apis salaries and hiring demand from live job postings.
The other 16 questions
This page shows 10 and marks what you pick. That's as far as a page can go. A free account opens the other 16 and keeps every answer. What you miss comes back until it's right: after a day, then at longer gaps.
Free · the whole bank · 100 marked answers per 30 days · written feedback on the paid plan