The Codex / Technologies / Express.js / Authentication

Authentication

Verifying who a user is - password hashing, JWT tokens, session-based auth, and protecting routes with middleware.

What it is, in plain English: Authentication answers 'who is this user?' -- as opposed to authorization, which answers 'what are they allowed to do?'. In Express, authentication typically means: hashing passwords before storing them (never plain text), verifying credentials on login, and issuing some form of proof (a session cookie or a JWT token) that the browser sends back on future requests so the server doesn't need to ask for a password every time.

Verifying who someone is

Step 1 -- never store plain text passwords

// npm install bcrypt
import bcrypt from "bcrypt";

// On registration -- hash before storing:
app.post("/register", async (req, res) => {
  const { email, password } = req.body;
  const hashedPassword = await bcrypt.hash(password, 10);   // 10 = salt rounds
  const user = await db.users.create({ email, password: hashedPassword });
  res.status(201).json({ id: user.id, email: user.email });
  // NEVER send the password (even hashed) back in the response
});

// On login -- compare the entered password against the stored hash:
app.post("/login", async (req, res) => {
  const { email, password } = req.body;
  const user = await db.users.findOne({ email });

  if (!user || !(await bcrypt.compare(password, user.password))) {
    return res.status(401).json({ error: "Invalid email or password" });
    // generic message -- don't reveal whether email exists (security)
  }

  // credentials are valid -- issue a token (next section)
});

Step 2 -- issue a JWT token on successful login

// npm install jsonwebtoken
import jwt from "jsonwebtoken";

app.post("/login", async (req, res) => {
  // ... verify password as above ...

  const token = jwt.sign(
    { userId: user.id },              // payload -- data to embed
    process.env.JWT_SECRET,            // secret key -- NEVER hardcode this
    { expiresIn: "1h" }                // token expires in 1 hour
  );

  res.json({ token });
});

// The client stores this token (localStorage or a cookie) and sends it
// with future requests: Authorization: Bearer <token>

Step 3 -- protect routes with middleware

function requireAuth(req, res, next) {
  const authHeader = req.headers.authorization;
  const token = authHeader?.replace("Bearer ", "");

  if (!token) {
    return res.status(401).json({ error: "No token provided" });
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;   // attach decoded payload to the request
    next();
  } catch {
    res.status(401).json({ error: "Invalid or expired token" });
  }
}

// Use it on any route that needs a logged-in user:
app.get("/profile", requireAuth, (req, res) => {
  res.json({ userId: req.user.userId });
});
Try It Yourself (Node.js logic)

Official Sources

The Codex links only to official documentation. No third-party tutorials.