0

Next.js & Node.js (Phần 7): Hoàn Thiện Hệ Thống Bảo Mật Với JWT Và Middleware

Chào mừng các bạn đến với bài viết cuối cùng trong chuỗi series xây dựng Website Fullstack. Sau khi đã có sản phẩm và giỏ hàng, việc thiết lập tài khoản người dùng là bước cuối cùng để hoàn thiện dự án. Hôm nay, chúng ta sẽ cùng nhau thực hiện cơ chế bảo mật "xịn xò" nhất.

Bài 1: Đăng Ký Tài Khoản & Mã Hóa Mật Khẩu

Lưu mật khẩu dưới dạng văn bản thuần (plain text) là một sai lầm chết người. Chúng ta sử dụng bcryptjs để "băm" (hash) mật khẩu trước khi lưu vào MongoDB.

Kỹ thuật lưu ý:

Phía Backend: Kiểm tra email đã tồn tại hay chưa trước khi tạo user mới.

Phía Frontend: Sử dụng combo Formik & Yup để validate dữ liệu ngay tại client (kiểm tra định dạng email, độ mạnh của mật khẩu và so khớp mật khẩu nhập lại).

// Mã hóa mật khẩu với độ phức tạp (salt) là 10
const hashPassword = await bcrypt.hash(password, 10);

Bài 2: Đăng Nhập & Quản Lý Phiên Với JWT (JSON Web Token)

Khi người dùng đăng nhập đúng, server sẽ tạo ra một chuỗi mã hóa gọi là Token. Token này giống như một "tấm thẻ thông hành" chứa thông tin định danh của người dùng.

Cách thức hoạt động:

User gửi Email & Password.

Server kiểm tra, nếu đúng sẽ tạo JWT chứa thông tin email và role.

Frontend nhận Token và lưu vào Cookie để sử dụng cho các yêu cầu sau này.

// Lưu token vào cookie với thời gian sống 1 tiếng
document.cookie = `token=${data.token}; path=/; max-age=3600`;

Bài 3: Bảo Vệ Route Với Middleware & Check Token

Làm sao để ngăn chặn những người dùng chưa đăng nhập truy cập vào trang Cá nhân (/info)? Câu trả lời là Next.js Middleware.

1. Phía Backend: API Check Token Chúng ta viết một API để giải mã Token và kiểm tra tính hợp lệ của nó (sử dụng jwt.verify).

2. Phía Frontend: middleware.js Middleware sẽ "đứng canh" ở cửa ngõ. Mỗi khi có yêu cầu truy cập vào /info, nó sẽ:

Kiểm tra xem trong Cookie có Token không.

Nếu có, gửi Token đó về Backend để xác thực.

Nếu không hợp lệ hoặc không có Token, lập tức chuyển hướng (Redirect) người dùng về trang Đăng nhập.

export const config = {
  matcher: '/info' // Chỉ áp dụng bảo vệ cho trang /info
};

Bài 4: Nâng Cấp Bảo Mật Cho Admin (Dành cho điểm 10)

Để hệ thống thực sự an toàn, trang Admin (/admin/*) phải được bảo vệ nghiêm ngặt hơn. Bạn cần viết một Middleware riêng để kiểm tra thuộc tính role trong Payload của JWT.

Nếu role === 'admin': Cho phép vào.

Nếu không: Chuyển hướng về trang chủ hoặc báo lỗi 403 Forbidden.

Tổng Kết Toàn Bộ Series FE2

Vậy là chúng ta đã cùng nhau đi từ con số 0 đến khi xây dựng thành công một ứng dụng Fullstack hoàn chỉnh:

Lab 1-2: Khởi tạo Backend, Database và hiển thị sản phẩm.

Lab 3: Tối ưu tương tác với useSWR và State.

Lab 4: Quản lý giỏ hàng toàn cục với Redux Toolkit.

Lab 5-6: Xây dựng Dashboard Admin, CRUD sản phẩm và Upload ảnh.

Lab 7: Bảo mật hệ thống với JWT và Middleware.

Đây là nền tảng vững chắc để bạn phát triển các dự án thực tế trong tương lai. Hy vọng chuỗi bài viết này đã mang lại nhiều giá trị cho các bạn.

Cảm ơn các bạn đã đồng hành và chúc các bạn bảo vệ đồ án thành công rực rỡ!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí