📖 Notes LESSON 27 OF 32

JWT Authentication

⏱️ 34 min
🟢 Node.js

Who Is Making This Request?

Never store plain-text passwords. Hash them with bcrypt, then issue a signed JSON Web Token on login so the server can verify who's calling protected routes without a database lookup on every request.

Hashing, Signing, Verifying

🔐
bcrypt
One-way hashes a password so even the database owner can't read the original.
🎫
JWT
A signed token containing user data — issued at login, sent on every future request.
✍️
jwt.sign()
Creates a token signed with a secret key, usually with an expiry time.
🛡️
Protect Middleware
Verifies the token on incoming requests before letting them reach protected routes.
Register, Login, Protect
JS
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');

// Register: hash before saving
const hashed = await bcrypt.hash(password, 10);
await User.create({ email, password: hashed });

// Login: compare + sign a token
const user = await User.findOne({ email });
const valid = await bcrypt.compare(password, user.password);
if (!valid) return res.status(401).json({ error: 'Invalid credentials' });

const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '7d' });
res.json({ token });

// Protect middleware
function protect(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'No token' });
  try {
    req.user = jwt.verify(token, process.env.JWT_SECRET);
    next();
  } catch {
    res.status(401).json({ error: 'Invalid token' });
  }
}

app.get('/api/profile', protect, (req, res) => res.json(req.user));
⚠️
Never hardcode the secret
The JWT secret must come from an environment variable, never committed to Git — anyone with it can forge valid tokens for any user.
🗒 Cheat Sheet 📝 Worksheet