Skip to content
Share
Explore

Authentication

STEP 1: USER VISITS LOGIN PAGE
─────────────────────────────────
GET /login
getLogin controller executes
├─ Check req.session.userId exists?
│ ├─ YES → isLoggedIn = true
│ └─ NO → isLoggedIn = false
Render login.ejs with isLoggedIn flag
User sees login form
STEP 2: USER SUBMITS CREDENTIALS
─────────────────────────────────
POST /login (email + password in body)
postLogin controller executes
├─ Query User table: WHERE email = req.body.email
│ ├─ NO MATCH → Log error, redirect /login
│ └─ MATCH → Proceed to password check
Validate password: bcrypt.compare(req.body.password, user.password)
├─ FALSE → Password incorrect, redirect /login
└─ TRUE → Proceed to session creation
Regenerate session (prevent session fixation)
req.session.regenerate((err) => { ... })
Store userId in session
req.session.userId = user.id
Save session to MySQL store
req.session.save((err) => { ... })
Redirect to home (/)
res.redirect('/')
STEP 3: AUTHENTICATED USER MAKES REQUEST
──────────────────────────────────────────
GET / (or any route)
Express-session middleware runs
├─ Read session cookie from browser
├─ Look up session in MySQL store
├─ Populate req.session.userId
└─ Pass control to next middleware
App-level middleware (app.js line ~66)
Check req.session.userId exists?
├─ YES → Fetch user from DB: User.findByPk(req.session.userId)
│ Cache in req.user object
│ Derive res.locals.isLoggedIn = true
│ Derive res.locals.isAdmin = user.isAdmin (from DB)
│ Pass res.locals.user = { id, name, email } to views
└─ NO → Set res.locals.user = null
Set res.locals.isLoggedIn = false
Set res.locals.isAdmin = false
Route handler executes
(user data available in req.user for logic, res.locals for templates)
If PUBLIC route (e.g., GET /) → Allow all users
If PROTECTED route (e.g., /my/cart) → Check before executing
├─ res.locals.isLoggedIn === false?
│ └─ YES → Reject, redirect /login
└─ YES → Allow, execute handler
If ADMIN route (e.g., /admin/write) → Check before executing
├─ res.locals.isAdmin === false?
│ └─ YES → Reject, redirect / (or 403 error)
└─ YES → Allow, execute handler
Handler sends response
├─ EJS templates can access: user, isLoggedIn, isAdmin
└─ JSON APIs can access: req.user
Browser receives response + session cookie (if modified, renewed)
STEP 4: USER LOGS OUT
──────────────────────
POST /logout (usually from button/form)
postLogout controller executes
Destroy session
req.session.destroy((err) => {
// Session removed from MySQL store
// Session cookie marked for deletion
})
Redirect to home (/)
res.redirect('/')
Browser deletes session cookie
Next request
├─ req.session.userId = undefined
├─ User treated as anonymous
└─ res.locals.isLoggedIn = false, res.locals.isAdmin = false


STEP 5: SESSION EXPIRATION (BACKGROUND)
────────────────────────────────────────
Session maxAge timeout occurs
(e.g., 7 days set in app.js)
express-mysql-session's cleanExpired job
(runs periodically, default every minute)
Old sessions deleted from MySQL store
User's next request has invalid session cookie
├─ Cookie points to non-existent session
├─ req.session.userId = undefined
└─ User auto-logged out
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.