Authentication helps websites know who you are. Session-based and token-based are two ways to do this simply and safely.
Session-based vs token-based auth in Node.js
Session-based:
// Server stores session info
req.session.user = { id: '123', name: 'Alice' };
Token-based:
// Server sends token to client
const token = jwt.sign({ id: '123' }, 'secret');
// Client sends token back in headers
Authorization: Bearer <token>Session-based stores user info on the server, linked by a cookie.
Token-based sends a signed token to the client, no server storage needed.
// Session-based example app.post('/login', (req, res) => { req.session.user = { id: '1', name: 'Bob' }; res.send('Logged in with session'); });
// Token-based example const jwt = require('jsonwebtoken'); app.post('/login', (req, res) => { const token = jwt.sign({ id: '1', name: 'Bob' }, 'secret'); res.json({ token }); });
This Node.js app shows both session-based and token-based login and profile routes. You can test login and then access profile routes to see how each method works.
import express from 'express'; import session from 'express-session'; import jwt from 'jsonwebtoken'; const app = express(); app.use(express.json()); // Session setup app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, cookie: { secure: false } })); // Session-based login app.post('/session-login', (req, res) => { req.session.user = { id: '42', name: 'Alice' }; res.send('Logged in with session'); }); // Session-based protected route app.get('/session-profile', (req, res) => { if (req.session.user) { res.send(`Hello ${req.session.user.name}, this is your session profile.`); } else { res.status(401).send('Not logged in'); } }); // Token-based login app.post('/token-login', (req, res) => { const token = jwt.sign({ id: '42', name: 'Alice' }, 'secret', { expiresIn: '1h' }); res.json({ token }); }); // Token-based protected route app.get('/token-profile', (req, res) => { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) return res.status(401).send('No token provided'); jwt.verify(token, 'secret', (err, user) => { if (err) return res.status(403).send('Invalid token'); res.send(`Hello ${user.name}, this is your token profile.`); }); }); app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Session-based auth keeps data on the server, so logout is easy by deleting the session.
Token-based auth is stateless, good for APIs and mobile apps, but logout needs token expiration or blacklist.
Always use HTTPS to keep cookies and tokens safe from attackers.
Session-based auth stores user info on the server linked by cookies.
Token-based auth sends a signed token to the client to prove identity.
Choose session for simple web apps, token for scalable or multi-device apps.
Practice
Solution
Step 1: Understand session-based auth storage
Session-based authentication stores user info on the server side, typically in memory or a database.Step 2: Identify how client links to session
The client receives a cookie that holds a session ID to link requests to the stored session data.Final Answer:
User data is stored on the server and linked to the client via cookies. -> Option AQuick Check:
Session-based auth = server stores data + cookie link [OK]
- Thinking tokens are stored on the server in session auth
- Confusing session ID with user credentials
- Assuming session data is stored on the client
Solution
Step 1: Identify Express.js method to set cookies
Express uses res.cookie() to set cookies on the client with options like httpOnly for security.Step 2: Match correct syntax for session cookie
res.cookie('sessionId', 'abc123', { httpOnly: true }) correctly sets a cookie named 'sessionId'.Final Answer:
res.cookie('sessionId', 'abc123', { httpOnly: true }); -> Option DQuick Check:
Use res.cookie() to set session cookies [OK]
- Using res.setHeader for cookies instead of Authorization header
- Assuming res.sendToken is a valid Express method
- Trying to set session with res.session which doesn't exist
const jwt = require('jsonwebtoken');
const token = req.headers.authorization?.split(' ')[1];
try {
const user = jwt.verify(token, 'secretKey');
res.send(`User ID: ${user.id}`);
} catch {
res.status(401).send('Unauthorized');
}Solution
Step 1: Extract token from Authorization header
The code splits the 'Authorization' header to get the token part after 'Bearer'.Step 2: Verify token and extract user info
jwt.verify checks the token with 'secretKey' and returns the decoded user object if valid.Final Answer:
User ID: [user's id from token] -> Option CQuick Check:
Valid token returns decoded user info [OK]
- Assuming token is printed directly without decoding
- Confusing token verification failure with syntax error
- Ignoring optional chaining and possible undefined token
function auth(req, res, next) {
if (!req.session.user) {
res.status(401).send('Not logged in');
}
next();
}Solution
Step 1: Analyze control flow after sending response
After res.status(401).send(), the function continues and calls next(), allowing unauthorized access.Step 2: Fix by adding return to stop execution
Adding return before res.status stops the function, preventing next() from running when unauthorized.Final Answer:
Missing return after sending 401 response causes next() to run anyway. -> Option BQuick Check:
Return after response to stop middleware [OK]
- Calling next() before checking session
- Confusing req.session.user with req.user
- Using res.sendStatus instead of res.status().send()
Solution
Step 1: Consider multi-device and scalability needs
Supporting multiple devices means the server should not rely on storing session state for each device.Step 2: Choose token-based auth for statelessness
Token-based auth uses signed tokens stored client-side, allowing stateless servers and easy scaling.Final Answer:
Token-based auth, because tokens are stateless and work well across devices. -> Option AQuick Check:
Stateless tokens = scalable multi-device auth [OK]
- Thinking sessions sync automatically across devices
- Believing token auth requires server session storage
- Choosing session auth for scalability
Ready to prove it?
Pass the test and this pattern moves unknown
