Loading lessons...
Project 2: User Authentication & JWT Auth Service
Build a Production Authentication Service
In this project, you will build user registration, login with bcrypt hashing, and JWT token protection.
Complete Auth Pipeline Code
const express = require("express");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const app = express();
app.use(express.json());
const JWT_SECRET = "jwt_super_secret_project_key";
const usersDB = []; // In-memory database array
// REGISTER ENDPOINT: POST /api/auth/register
app.post("/api/auth/register", async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ error: "Email and password are required" });
}
const existingUser = usersDB.find(u => u.email === email);
if (existingUser) {
return res.status(409).json({ error: "User already exists" });
}
// Hash password with bcrypt
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = { id: usersDB.length + 1, email, password: hashedPassword };
usersDB.push(newUser);
res.status(201).json({ status: "success", message: "User registered successfully" });
});
// LOGIN ENDPOINT: POST /api/auth/login
app.post("/api/auth/login", async (req, res) => {
const { email, password } = req.body;
const user = usersDB.find(u => u.email === email);
if (!user) {
return res.status(401).json({ error: "Invalid credentials" });
}
// Compare entered password with stored bcrypt hash
const isValid = await bcrypt.compare(password, user.password);
if (!isValid) {
return res.status(401).json({ error: "Invalid credentials" });
}
// Sign JWT token
const token = jwt.sign({ userId: user.id, email: user.email }, JWT_SECRET, { expiresIn: "2h" });
res.status(200).json({ status: "success", token });
});
// PROTECTED DASHBOARD: GET /api/auth/profile
app.get("/api/auth/profile", (req, res) => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return res.status(401).json({ error: "Access denied" });
}
const token = authHeader.split(" ")[1];
try {
const decoded = jwt.verify(token, JWT_SECRET);
res.status(200).json({ status: "success", user: decoded });
} catch (err) {
res.status(403).json({ error: "Invalid or expired token" });
}
});
TL;DR
- Hash passwords during registration using
bcrypt.hash. - Compare hashes during login using
bcrypt.compare. - Issue JWT tokens and protect secure routes via Authorization Bearer headers.