CodingNic

Session-Based Authentication

Exercises

Session-Based Authentication 30 min read

Exercises

Objectives

By the end of this lesson, you should be able to:

  • Build a protected endpoint that requires both a valid session and a correct current password
  • Confirm a password change actually takes effect for future logins
  • Confirm an old password stops working immediately after a change

⚠️ A note on verification: every command and every output in this lesson was actually run, with real HTTP requests against a real Express app.

Exercise: Change Password While Logged In

a) Build the endpoint. POST /api/v1/auth/change-password, protected by requireAuth (Lesson 3), requiring the current password to match before setting a new one:

javascript
app.post('/api/v1/auth/change-password', requireAuth, async (req, res, next) => {
  try {
    const { currentPassword, newPassword } = req.body;
    const user = users.find(u => u.id === req.session.userId);
    const matches = await bcrypt.compare(currentPassword, user.passwordHash);
    if (!matches) {
      return res.status(401).json({ error: 'InvalidCredentials', message: 'Current password is incorrect' });
    }
    user.passwordHash = await bcrypt.hash(newPassword, 10);
    res.status(204).send();
  } catch (err) {
    next(err);
  }
});

b) Test an anonymous attempt. No session at all:

text
ANON ATTEMPT: 401 {"error":"Unauthorized","message":"Login required"}

c) Test a wrong current password, logged in, but the wrong currentPassword:

text
WRONG CURRENT: 401 {"error":"InvalidCredentials","message":"Current password is incorrect"}

d) Test a successful change:

text
SUCCESS: 204

e) Confirm the new password actually works, log in again, from a fresh client, with the new password:

text
RE-LOGIN WITH NEW PASSWORD: 200 {"id":1,"email":"erin@example.com"}

f) Confirm the old password no longer works:

text
OLD PASSWORD NO LONGER WORKS: 401 {"error":"InvalidCredentials","message":"Incorrect email or password"}

g) Add a stronger guarantee. Modify the endpoint so it also calls req.session.destroy() after a successful password change, forcing the user to log in again with the new password on their next request too, not just other clients. Confirm, with a test, that the current session’s own follow-up request to a protected route now also returns 401.

Recap

This module covered the complete session-based authentication flow: how sessions work conceptually, wiring up express-session, and building login, logout, and protected routes, including a password-change endpoint that requires both an active session and the correct current password.

Next module: JSON Web Tokens, a stateless alternative to sessions, the pattern most REST APIs use instead.