6.9 KiB
6.9 KiB
Authentication
Chức năng 1: Layout cơ bản (Header, Footer, Navbar, SidebarAdmin)
Mục tiêu
Tạo layout nền tảng cho toàn bộ hệ thống và cấu trúc render nội dung theo route.
Nhiệm vụ chi tiết
- Tạo thư mục:
src/components/layouts/ - Bao gồm:
- Header.jsx
- Footer.jsx
- Navbar.jsx
- SidebarAdmin.jsx
- LayoutMain.jsx
- Dùng trong LayoutMain để render nội dung động.
- Navbar thay đổi tùy trạng thái đăng nhập:
- Nếu chưa login → hiển thị nút “Đăng nhập / Đăng ký”.
- Nếu đã login → hiển thị avatar, tên user và nút “Đăng xuất”.
- SidebarAdmin chỉ hiển thị với role = admin.
Kết quả mong đợi
- Layout tổng thể hiển thị ổn định.
- Navbar hiển thị nội dung động theo trạng thái người dùng.
- Giao diện responsive, tương thích desktop/mobile.
Chức năng 2: Cấu hình Routing (react-router-dom)
Mục tiêu
Thiết lập hệ thống định tuyến chuẩn, có bảo vệ route theo role.
Nhiệm vụ chi tiết
- Cấu trúc route chính:
<Route path="/" element={<LayoutMain />}> <Route index element={<HomePage />} /> <Route path="rooms" element={<RoomListPage />} /> <Route path="bookings" element={<BookingListPage />} /> </Route> <Route path="/login" element={<LoginPage />} /> <Route path="/register" element={<RegisterPage />} /> <Route path="/forgot-password" element={<ForgotPasswordPage />} /> <Route path="/reset-password/:token" element={<ResetPasswordPage />} /> <Route path="/dashboard" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} /> <Route path="/admin/*" element={<AdminRoute><AdminModule /></AdminRoute>} /> - Dùng ProtectedRoute và AdminRoute để kiểm tra:
- isAuthenticated
- role === "admin"
Kết quả mong đợi
- Người dùng không đăng nhập bị redirect về /login.
- AdminRoute chỉ cho phép admin truy cập.
- Tất cả route hoạt động mượt, không lỗi vòng lặp redirect.
Chức năng 3: useAuthStore (Zustand Store)
Mục tiêu
Quản lý trạng thái xác thực toàn cục (token, userInfo, role).
Nhiệm vụ chi tiết
- Tạo src/stores/useAuthStore.js
- Cấu trúc:
const useAuthStore = create((set) => ({ token: localStorage.getItem("token") || null, userInfo: JSON.parse(localStorage.getItem("userInfo")) || null, isAuthenticated: !!localStorage.getItem("token"), login: async (credentials) => { ... }, logout: () => { ... }, setUser: (user) => { ... }, resetPassword: async (payload) => { ... }, })); - Khi đăng nhập thành công:
- Lưu token + userInfo vào localStorage.
- Khi logout:
- Xóa localStorage và reset state.
Kết quả mong đợi
- Toàn bộ thông tin user được quản lý tập trung.
- Duy trì đăng nhập sau khi reload trang.
- Dễ dàng truy cập userInfo trong mọi component.
Chức năng 4: Form Login
Mục tiêu
Cho phép người dùng đăng nhập hệ thống.
Nhiệm vụ chi tiết
- Tạo LoginPage.jsx
- Dùng React Hook Form + Yup validate:
- Email hợp lệ
- Mật khẩu ≥ 8 ký tự
- API:
POST /api/auth/login - Sau khi đăng nhập thành công:
- Lưu token vào localStorage.
- Gọi setUser() để cập nhật Zustand.
- Redirect về /dashboard.
- Gửi email POST /api/notify/login-success.
- UX nâng cao:
- Nút loading khi đang gửi form.
- “Hiện/Ẩn mật khẩu”.
- “Nhớ đăng nhập” → lưu 7 ngày.
Kết quả mong đợi
- Đăng nhập hoạt động mượt, hiển thị thông báo lỗi rõ ràng.
- Email được gửi khi login thành công.
- Chuyển hướng đúng theo vai trò user.
Chức năng 5: Form Register
Mục tiêu
Cho phép người dùng đăng ký tài khoản mới.
Nhiệm vụ chi tiết
- Tạo RegisterPage.jsx
- Dùng React Hook Form + Yup validate:
- Họ tên không rỗng
- Email hợp lệ
- Mật khẩu ≥ 8 ký tự, có ký tự đặc biệt
- API:
POST /api/auth/register - Sau khi đăng ký thành công:
- Hiển thị toast “Đăng ký thành công, vui lòng đăng nhập”.
- Redirect về /login.
Kết quả mong đợi
- Người dùng tạo tài khoản mới thành công.
- Validate chặt chẽ, UX mượt mà.
- Giao diện thống nhất với form login.
Chức năng 6: Quên mật khẩu (Forgot Password)
Mục tiêu
Cung cấp chức năng gửi email reset mật khẩu.
Nhiệm vụ chi tiết
- Tạo ForgotPasswordPage.jsx
- API:
POST /api/auth/forgot-password - Sau khi gửi thành công:
- Hiển thị thông báo “Vui lòng kiểm tra email để đặt lại mật khẩu.”
- Backend gửi link reset có token dạng:
https://domain.com/reset-password/:token
Kết quả mong đợi
- Gửi email thành công.
- UX rõ ràng, có loading và thông báo lỗi.
- Giao diện thân thiện.
Chức năng 7: Đặt lại mật khẩu (Reset Password)
Mục tiêu
Cho phép người dùng đổi mật khẩu thông qua link email.
Nhiệm vụ chi tiết
- Tạo ResetPasswordPage.jsx
- Validate:
- Mật khẩu mới ≥ 8 ký tự, chứa ký tự đặc biệt
- Nhập lại mật khẩu trùng khớp
- API:
POST /api/auth/reset-password - Sau khi đổi mật khẩu thành công:
- Gửi email xác nhận POST /api/notify/reset-success.
- Redirect về /login.
Kết quả mong đợi
- Mật khẩu được cập nhật thành công.
- Gửi email thông báo thành công.
- Bảo vệ token hết hạn (invalid token → redirect về forgot-password).
Chức năng 8: Phân quyền & Bảo vệ route (ProtectedRoute / AdminRoute)
Mục tiêu
Chặn truy cập trái phép và bảo vệ các route quan trọng.
Nhiệm vụ chi tiết
-
Tạo component ProtectedRoute.jsx:
const ProtectedRoute = ({ children }) => { const { isAuthenticated } = useAuthStore(); const location = useLocation(); return isAuthenticated ? children : <Navigate to="/login" state={{ from: location }} replace />; }; -
Tạo AdminRoute.jsx:
const AdminRoute = ({ children }) => { const { userInfo } = useAuthStore(); return userInfo?.role === "admin" ? children : <Navigate to="/" replace />; };
Kết quả mong đợi
- Chỉ người dùng hợp lệ mới truy cập được route quan trọng.
- AdminRoute đảm bảo bảo mật cho module quản trị.