Skip to content

Module Recap

Module 06 secured the Bulletin API. Users can now register and log in; protected routes know who’s making each request; and the server is hardened against common attacks.

Authentication and authorization are distinct. Authentication answers “who are you?” — verified by credentials. Authorization answers “what can you do?” — enforced in route logic. 401 means unauthenticated; 403 means authenticated but forbidden.

bcrypt hashes passwords one-way. Never store plain text. bcrypt.hash() produces a 60-character hash from a password; bcrypt.compare() verifies without reversing. Salt rounds control computational cost — 12 is a good default.

JWTs are self-contained identity tokens. Signed with a secret key that only the server knows. jwt.sign() creates a token; jwt.verify() validates it or throws. The payload carries userId and username — no database lookup needed per request.

The authenticate middleware is the gatekeeper. It reads Authorization: Bearer <token>, verifies the JWT, and attaches the payload to res.locals.user. Apply it per-route where authentication is required.

CORS, Helmet, and rate limiting harden the API. CORS controls which origins can call the API. Helmet adds security headers with one line. Rate limiting prevents brute-force attacks — stricter limits on auth endpoints.

POST /auth/register
body: { username, password }
→ bcrypt.hash(password, 12) → password_hash
→ INSERT INTO users
→ jwt.sign({ userId, username }) → token
→ return { token, userId, username }
POST /auth/login
body: { username, password }
→ SELECT user by username
→ bcrypt.compare(password, user.password_hash)
→ jwt.sign({ userId, username }) → token
→ return { token, userId, username }
POST /posts (protected)
header: Authorization: Bearer <token>
→ authenticate middleware: jwt.verify(token) → payload
→ res.locals.user = { userId, username }
→ controller: INSERT INTO posts (... user_id = res.locals.user.userId)
TermWhat it means
AuthenticationVerifying identity — who are you?
AuthorizationControlling access — what can you do?
401Unauthenticated — no valid token
403Unauthorized — valid token, but not allowed
bcryptOne-way password hashing algorithm
Salt roundsbcrypt cost factor — higher = slower = more secure
JWTJSON Web Token — signed, self-contained identity assertion
jwt.sign(payload, secret)Creates a token
jwt.verify(token, secret)Validates a token or throws
res.locals.userRequest-scoped authenticated user data
CORSAllows cross-origin requests from specified origins
HelmetSets security headers (one line)
Rate limitingThrottles requests to prevent abuse

Module 07 — Bulletin API Build →

Module 07 assembles everything into the complete Bulletin backend. You’ll design the final schema, build user registration and login, implement posts and comments endpoints, and deploy the API to Railway. By the end, you’ll have a live, working backend that the React frontend will connect to in Part 2.