JWT authentication flow helps keep users logged in safely by using tokens. It makes sure only the right people can access certain parts of a website or app.
JWT authentication flow in Astro
1. User sends login info (like username and password) to server. 2. Server checks info and creates a JWT token if correct. 3. Server sends JWT token back to user. 4. User stores token (usually in localStorage or cookies). 5. User sends token with requests to access protected data. 6. Server checks token to allow or deny access.
The JWT token is a string with three parts separated by dots: header, payload, and signature.
Tokens are usually sent in HTTP headers like Authorization: Bearer <token>.
POST /login
Request body: { username: 'user1', password: 'pass123' }
Response: { token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' }GET /profile
Headers: Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Response: { name: 'User One', email: 'user1@example.com' }This Astro example shows a simple login that returns a JWT token and a protected route that checks the token before greeting the user.
import jwt from 'jsonwebtoken'; const SECRET = 'mysecretkey'; // Simulate user database const users = [{ username: 'user1', password: 'pass123' }]; // Login handler export async function POST({ request }) { const { username, password } = await request.json(); const user = users.find(u => u.username === username && u.password === password); if (!user) { return new Response(JSON.stringify({ error: 'Invalid login' }), { status: 401 }); } const token = jwt.sign({ username: user.username }, SECRET, { expiresIn: '1h' }); return new Response(JSON.stringify({ token }), { status: 200 }); } // Protected route example export async function GET({ request }) { const authHeader = request.headers.get('Authorization'); if (!authHeader || !authHeader.startsWith('Bearer ')) { return new Response(JSON.stringify({ error: 'No token provided' }), { status: 401 }); } const token = authHeader.split(' ')[1]; try { const payload = jwt.verify(token, SECRET); return new Response(JSON.stringify({ message: `Hello, ${payload.username}!` }), { status: 200 }); } catch { return new Response(JSON.stringify({ error: 'Invalid token' }), { status: 401 }); } }
Always keep your secret key safe and never share it publicly.
Tokens expire to keep things secure; users may need to log in again after expiration.
Store tokens securely in the browser to avoid security risks like cross-site scripting.
JWT authentication uses tokens to keep users logged in safely.
Tokens are sent with requests to access protected parts of an app.
Servers check tokens to allow or deny access.
Practice
Solution
Step 1: Understand JWT role in authentication
JWTs carry encoded user identity and permissions safely between client and server.Step 2: Compare options with JWT purpose
Only To securely transmit user identity and permissions between client and server correctly describes JWT's role; others confuse JWT with password storage or encryption.Final Answer:
To securely transmit user identity and permissions between client and server -> Option AQuick Check:
JWT purpose = secure token for identity [OK]
- Thinking JWT stores passwords
- Confusing JWT with database encryption
- Assuming JWT replaces cookies entirely
Solution
Step 1: Recall standard JWT header format
The standard way to send JWT is in the Authorization header with 'Bearer' prefix.Step 2: Match options to standard
Only Authorization: Bearer <token> matches the correct syntax: 'Authorization: Bearer <token>'. Others use incorrect header names or formats.Final Answer:
Authorization: Bearer <token> -> Option AQuick Check:
JWT header = Authorization: Bearer token [OK]
- Using wrong header names like 'Token' or 'Auth-Token'
- Omitting 'Bearer' prefix
- Adding extra words like 'JWT' before token
import jwt from 'jsonwebtoken';
export async function get({ request }) {
const authHeader = request.headers.get('Authorization');
if (!authHeader) return new Response('No token', { status: 401 });
const token = authHeader.split(' ')[1];
try {
const user = jwt.verify(token, 'secretkey');
return new Response(`User: ${user.name}`, { status: 200 });
} catch {
return new Response('Invalid token', { status: 403 });
}
}Solution
Step 1: Analyze token verification flow
If token is invalid, jwt.verify throws an error caught by catch block.Step 2: Check catch block response
The catch block returns status 403 with message 'Invalid token'.Final Answer:
Response with status 403 and message 'Invalid token' -> Option CQuick Check:
Invalid token triggers 403 response [OK]
- Assuming invalid token returns 401
- Confusing catch block with success path
- Expecting server error instead of 403
export async function get({ request }) {
const authHeader = request.headers.get('Authorization');
if (!authHeader) return new Response('No token', { status: 401 });
const token = authHeader.split(' ')[0];
try {
const user = jwt.verify(token, 'secretkey');
return new Response(`User: ${user.name}`, { status: 200 });
} catch {
return new Response('Invalid token', { status: 403 });
}
}Solution
Step 1: Check how token is extracted
Token is extracted using authHeader.split(' ')[0], which gets 'Bearer' instead of the token.Step 2: Identify correct token index
The token is at index 1 after splitting by space, so index 0 is wrong.Final Answer:
Token extraction uses wrong index from split -> Option BQuick Check:
Token index must be 1, not 0 [OK]
- Using split index 0 instead of 1
- Forgetting to check Authorization header
- Mixing up status codes 401 and 403
Solution
Step 1: Understand secure token storage
Access tokens should be stored in memory to reduce exposure; refresh tokens in HttpOnly cookies to prevent JavaScript access.Step 2: Use refresh token to get new access token
When access token expires, client uses refresh token securely to request a new access token.Final Answer:
Store access token in memory and refresh token in HttpOnly cookie; use refresh token to get new access token when expired -> Option DQuick Check:
Secure refresh flow = memory + HttpOnly cookie [OK]
- Storing tokens in localStorage (XSS risk)
- Never refreshing tokens (causes logout)
- Putting tokens in URL (exposes tokens)
Ready to prove it?
Pass the test and this pattern moves unknown
