Chapter 9 of 10
Authentication is the process of verifying who a user is. The most common approach in modern APIs is JSON Web Tokens (JWT) โ stateless tokens that the client sends with every request.
npm install jsonwebtoken bcryptjsconst jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
// REGISTER โ hash password, save user
app.post("/api/auth/register", async (req, res, next) => {
try {
const { name, email, password } = req.body;
const hash = await bcrypt.hash(password, 12); // 12 rounds
const user = await User.create({ name, email, password: hash });
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, {
expiresIn: "7d",
});
res.status(201).json({ token });
} catch (err) { next(err); }
});
// LOGIN โ verify password, issue token
app.post("/api/auth/login", async (req, res, next) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user || !(await bcrypt.compare(password, user.password))) {
return res.status(401).json({ error: "Invalid credentials" });
}
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: "7d" });
res.json({ token });
} catch (err) { next(err); }
});
// MIDDLEWARE โ protect routes
function authenticate(req, res, next) {
const auth = req.headers.authorization;
if (!auth?.startsWith("Bearer ")) return res.status(401).json({ error: "No token" });
try {
const payload = jwt.verify(auth.slice(7), process.env.JWT_SECRET);
req.user = payload;
next();
} catch {
res.status(401).json({ error: "Invalid token" });
}
}
// Use on protected routes
app.get("/api/me", authenticate, (req, res) => {
res.json({ userId: req.user.id });
});