Hướng Dẫn Xác Thực Trong Express Với Mongoose và JWT
Xác thực là một trong những phần quan trọng nhất của bất kỳ ứng dụng web nào. Nếu không có nó, người dùng của bạn sẽ không thể đăng nhập một cách an toàn, truy cập dữ liệu của họ hoặc tin tưởng vào ứng dụng của bạn. Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách triển khai xác thực trong Express.js bằng cách sử dụng Mongoose và JWT (JSON Web Tokens).
Mục tiêu
Cuối cùng, bạn sẽ có một thiết lập làm việc với các chức năng Đăng Ký, Đăng Nhập và Các Đường Dẫn Bảo Vệ.
Mục Lục
- Bước 1: Thiết lập Dự Án
- Bước 2: Kết Nối với MongoDB
- Bước 3: Tạo Mô Hình Người Dùng
- Bước 4: Đường Dẫn Xác Thực (Đăng Ký & Đăng Nhập)
- Bước 5: Middleware Bảo Vệ Đường Dẫn
- Thực Hành Tốt Nhất
- Kết Luận
Bước 1: Thiết lập Dự Án
Khởi tạo một dự án mới:
bash
mkdir express-auth && cd express-auth
npm init -y
Cài đặt các phụ thuộc:
bash
npm install express mongoose bcrypt jsonwebtoken dotenv cors
npm install --save-dev nodemon
Cấu trúc Dự Án:
📂 express-auth
┣ 📂 models
┃ ┗ user.model.js
┣ 📂 routes
┃ ┗ auth.routes.js
┣ 📂 middlewares
┃ ┗ auth.middleware.js
┣ server.js
┣ .env
Bước 2: Kết Nối với MongoDB
Trong server.js, thêm mã sau:
javascript
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";
import cors from "cors";
dotenv.config();
const app = express();
app.use(express.json());
app.use(cors());
mongoose
.connect(process.env.MONGO_URI)
.then(() => console.log("MongoDB connected"))
.catch((err) => console.error(err));
app.listen(5000, () => console.log("Server running on port 5000"));
Bước 3: Tạo Mô Hình Người Dùng
Trong models/user.model.js, tạo mã sau:
javascript
import mongoose from "mongoose";
import bcrypt from "bcrypt";
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
// Hash password trước khi lưu
userSchema.pre("save", async function (next) {
if (!this.isModified("password")) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
});
const User = mongoose.model("User", userSchema);
export default User;
Bước 4: Đường Dẫn Xác Thực (Đăng Ký & Đăng Nhập)
Trong routes/auth.routes.js, thêm mã sau:
javascript
import express from "express";
import jwt from "jsonwebtoken";
import bcrypt from "bcrypt";
import User from "../models/user.model.js";
const router = express.Router();
// Đăng Ký
router.post("/register", async (req, res) => {
try {
const { name, email, password } = req.body;
const existing = await User.findOne({ email });
if (existing) return res.status(400).json({ message: "Người dùng đã tồn tại" });
const user = new User({ name, email, password });
await user.save();
res.status(201).json({ message: "Người dùng đã đăng ký thành công" });
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// Đăng Nhập
router.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user) return res.status(400).json({ message: "Thông tin xác thực không hợp lệ" });
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ message: "Thông tin xác thực không hợp lệ" });
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: "1h" });
res.json({ token, user: { id: user._id, name: user.name, email: user.email } });
} catch (err) {
res.status(500).json({ message: err.message });
}
});
export default router;
Bước 5: Middleware Bảo Vệ Đường Dẫn
Trong middlewares/auth.middleware.js, thêm mã sau:
javascript
import jwt from "jsonwebtoken";
export const authMiddleware = (req, res, next) => {
const token = req.headers.authorization?.split(" ")[1]; // Bearer <token>
if (!token) return res.status(401).json({ message: "Không có token" });
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch {
res.status(401).json({ message: "Token không hợp lệ" });
}
};
Thực Hành Tốt Nhất
- 🔒 Không bao giờ lưu trữ mật khẩu dưới dạng văn bản thường. Luôn luôn băm chúng.
- ⏳ Sử dụng JWT ngắn hạn + mã thông báo làm mới cho các phiên dài hạn.
- 🔑 Giữ bí mật JWT_SECRET của bạn an toàn và bên ngoài mã nguồn.
- 🍪 Ưu tiên sử dụng cookie HttpOnly để lưu trữ token trong môi trường sản xuất.
- 🌐 Luôn sử dụng HTTPS trong môi trường sản xuất.
Kết Luận
Bạn vừa xây dựng thành công hệ thống xác thực trong Express với Mongoose và JWT! Chúng ta đã tạo một mô hình Người Dùng, thêm các đường dẫn Đăng Ký/Đăng Nhập, tạo token JWT và bảo vệ các đường dẫn với middleware.
👉 Các bước tiếp theo:
- Thêm phân quyền dựa trên vai trò (quản trị viên, người dùng, v.v.)
- Triển khai mã thông báo làm mới cho các phiên dài hơn.
- Thêm OAuth (đăng nhập Google/GitHub).
🔥 Đó là tất cả! Giờ đây, bạn đã có một hệ thống xác thực an toàn trong ứng dụng Express của mình.