update
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
# useAuthStore - Zustand Authentication Store
|
||||
|
||||
## ✅ Hoàn thành Chức năng 3
|
||||
## ✅ Function 3 Completed
|
||||
|
||||
### 📦 Files đã tạo:
|
||||
### 📦 Files Created:
|
||||
|
||||
1. **`src/store/useAuthStore.ts`** - Zustand store quản lý auth
|
||||
2. **`src/services/api/apiClient.ts`** - Axios client với interceptors
|
||||
1. **`src/store/useAuthStore.ts`** - Zustand store managing auth
|
||||
2. **`src/services/api/apiClient.ts`** - Axios client with interceptors
|
||||
3. **`src/services/api/authService.ts`** - Auth API service
|
||||
4. **`.env.example`** - Template cho environment variables
|
||||
4. **`.env.example`** - Template for environment variables
|
||||
|
||||
### 🎯 Tính năng đã implement:
|
||||
### 🎯 Features Implemented:
|
||||
|
||||
#### State Management:
|
||||
```typescript
|
||||
@@ -24,19 +24,19 @@ interface AuthState {
|
||||
```
|
||||
|
||||
#### Actions:
|
||||
- ✅ `login(credentials)` - Đăng nhập
|
||||
- ✅ `register(data)` - Đăng ký tài khoản mới
|
||||
- ✅ `logout()` - Đăng xuất
|
||||
- ✅ `setUser(user)` - Cập nhật thông tin user
|
||||
- ✅ `refreshAuthToken()` - Làm mới token
|
||||
- ✅ `forgotPassword(data)` - Quên mật khẩu
|
||||
- ✅ `resetPassword(data)` - Đặt lại mật khẩu
|
||||
- ✅ `initializeAuth()` - Khởi tạo auth từ localStorage
|
||||
- ✅ `clearError()` - Xóa error message
|
||||
- ✅ `login(credentials)` - Login
|
||||
- ✅ `register(data)` - Register new account
|
||||
- ✅ `logout()` - Logout
|
||||
- ✅ `setUser(user)` - Update user information
|
||||
- ✅ `refreshAuthToken()` - Refresh token
|
||||
- ✅ `forgotPassword(data)` - Forgot password
|
||||
- ✅ `resetPassword(data)` - Reset password
|
||||
- ✅ `initializeAuth()` - Initialize auth from localStorage
|
||||
- ✅ `clearError()` - Clear error message
|
||||
|
||||
### 📝 Cách sử dụng:
|
||||
### 📝 Usage:
|
||||
|
||||
#### 1. Khởi tạo trong App.tsx:
|
||||
#### 1. Initialize in App.tsx:
|
||||
```typescript
|
||||
import useAuthStore from './store/useAuthStore';
|
||||
|
||||
@@ -56,7 +56,7 @@ function App() {
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Sử dụng trong Login Form:
|
||||
#### 2. Use in Login Form:
|
||||
```typescript
|
||||
import useAuthStore from '../store/useAuthStore';
|
||||
|
||||
@@ -67,9 +67,9 @@ const LoginPage = () => {
|
||||
const handleSubmit = async (data) => {
|
||||
try {
|
||||
await login(data);
|
||||
navigate('/dashboard'); // Redirect sau khi login
|
||||
navigate('/dashboard'); // Redirect after login
|
||||
} catch (error) {
|
||||
// Error đã được xử lý bởi store
|
||||
// Error has been handled by store
|
||||
}
|
||||
};
|
||||
|
||||
@@ -78,14 +78,14 @@ const LoginPage = () => {
|
||||
{/* Form fields */}
|
||||
{error && <div>{error}</div>}
|
||||
<button disabled={isLoading}>
|
||||
{isLoading ? 'Đang xử lý...' : 'Đăng nhập'}
|
||||
{isLoading ? 'Processing...' : 'Login'}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
#### 3. Sử dụng trong Register Form:
|
||||
#### 3. Use in Register Form:
|
||||
```typescript
|
||||
const RegisterPage = () => {
|
||||
const { register, isLoading } = useAuthStore();
|
||||
@@ -94,9 +94,9 @@ const RegisterPage = () => {
|
||||
const handleSubmit = async (data) => {
|
||||
try {
|
||||
await register(data);
|
||||
navigate('/login'); // Redirect về login
|
||||
navigate('/login'); // Redirect to login
|
||||
} catch (error) {
|
||||
// Error được hiển thị qua toast
|
||||
// Error displayed via toast
|
||||
}
|
||||
};
|
||||
|
||||
@@ -111,21 +111,21 @@ const Header = () => {
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout();
|
||||
// Auto redirect về login nếu cần
|
||||
// Auto redirect to login if needed
|
||||
};
|
||||
|
||||
return <button onClick={handleLogout}>Đăng xuất</button>;
|
||||
return <button onClick={handleLogout}>Logout</button>;
|
||||
};
|
||||
```
|
||||
|
||||
#### 5. Hiển thị thông tin user:
|
||||
#### 5. Display user information:
|
||||
```typescript
|
||||
const Profile = () => {
|
||||
const { userInfo } = useAuthStore();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Xin chào, {userInfo?.name}</h1>
|
||||
<h1>Hello, {userInfo?.name}</h1>
|
||||
<p>Email: {userInfo?.email}</p>
|
||||
<p>Role: {userInfo?.role}</p>
|
||||
</div>
|
||||
@@ -135,68 +135,68 @@ const Profile = () => {
|
||||
|
||||
### 🔐 LocalStorage Persistence:
|
||||
|
||||
Store tự động lưu và đọc từ localStorage:
|
||||
Store automatically saves and reads from localStorage:
|
||||
- `token` - JWT access token
|
||||
- `refreshToken` - JWT refresh token
|
||||
- `userInfo` - Thông tin user
|
||||
- `userInfo` - User information
|
||||
|
||||
Khi reload page, auth state được khôi phục tự động qua `initializeAuth()`.
|
||||
When page reloads, auth state is automatically restored via `initializeAuth()`.
|
||||
|
||||
### 🌐 API Integration:
|
||||
|
||||
#### Base URL Configuration:
|
||||
Tạo file `.env` trong thư mục `client/`:
|
||||
Create `.env` file in `client/` directory:
|
||||
```env
|
||||
VITE_API_URL=http://localhost:3000
|
||||
VITE_ENV=development
|
||||
```
|
||||
|
||||
#### API Endpoints được sử dụng:
|
||||
- `POST /api/auth/login` - Đăng nhập
|
||||
- `POST /api/auth/register` - Đăng ký
|
||||
- `POST /api/auth/logout` - Đăng xuất
|
||||
- `GET /api/auth/profile` - Lấy profile
|
||||
#### API Endpoints Used:
|
||||
- `POST /api/auth/login` - Login
|
||||
- `POST /api/auth/register` - Register
|
||||
- `POST /api/auth/logout` - Logout
|
||||
- `GET /api/auth/profile` - Get profile
|
||||
- `POST /api/auth/refresh-token` - Refresh token
|
||||
- `POST /api/auth/forgot-password` - Quên mật khẩu
|
||||
- `POST /api/auth/reset-password` - Đặt lại mật khẩu
|
||||
- `POST /api/auth/forgot-password` - Forgot password
|
||||
- `POST /api/auth/reset-password` - Reset password
|
||||
|
||||
### 🛡️ Security Features:
|
||||
|
||||
1. **Auto Token Injection**:
|
||||
- Axios interceptor tự động thêm token vào headers
|
||||
- Axios interceptor automatically adds token to headers
|
||||
```typescript
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
2. **Auto Logout on 401**:
|
||||
- Khi token hết hạn (401), tự động logout và redirect về login
|
||||
- When token expires (401), automatically logout and redirect to login
|
||||
|
||||
3. **Token Refresh**:
|
||||
- Có thể refresh token khi sắp hết hạn
|
||||
- Can refresh token when about to expire
|
||||
|
||||
4. **Password Hashing**:
|
||||
- Backend xử lý bcrypt hashing
|
||||
- Backend handles bcrypt hashing
|
||||
|
||||
### 📱 Toast Notifications:
|
||||
|
||||
Store tự động hiển thị toast cho các events:
|
||||
- ✅ Login thành công
|
||||
- ✅ Đăng ký thành công
|
||||
Store automatically displays toast for events:
|
||||
- ✅ Login successful
|
||||
- ✅ Registration successful
|
||||
- ✅ Logout
|
||||
- ❌ Login thất bại
|
||||
- ❌ Đăng ký thất bại
|
||||
- ❌ Login failed
|
||||
- ❌ Registration failed
|
||||
- ❌ API errors
|
||||
|
||||
### 🔄 Component Updates:
|
||||
|
||||
#### ProtectedRoute:
|
||||
```typescript
|
||||
// TRƯỚC (với props)
|
||||
// BEFORE (with props)
|
||||
<ProtectedRoute isAuthenticated={isAuthenticated}>
|
||||
<Dashboard />
|
||||
</ProtectedRoute>
|
||||
|
||||
// SAU (tự động lấy từ store)
|
||||
// AFTER (automatically gets from store)
|
||||
<ProtectedRoute>
|
||||
<Dashboard />
|
||||
</ProtectedRoute>
|
||||
@@ -204,19 +204,19 @@ Store tự động hiển thị toast cho các events:
|
||||
|
||||
#### AdminRoute:
|
||||
```typescript
|
||||
// TRƯỚC (với props)
|
||||
// BEFORE (with props)
|
||||
<AdminRoute userInfo={userInfo}>
|
||||
<AdminPanel />
|
||||
</AdminRoute>
|
||||
|
||||
// SAU (tự động lấy từ store)
|
||||
// AFTER (automatically gets from store)
|
||||
<AdminRoute>
|
||||
<AdminPanel />
|
||||
</AdminRoute>
|
||||
```
|
||||
|
||||
#### LayoutMain:
|
||||
Vẫn nhận props từ App.tsx để hiển thị Header/Navbar:
|
||||
Still receives props from App.tsx to display Header/Navbar:
|
||||
```typescript
|
||||
<LayoutMain
|
||||
isAuthenticated={isAuthenticated}
|
||||
@@ -227,44 +227,44 @@ Vẫn nhận props từ App.tsx để hiển thị Header/Navbar:
|
||||
|
||||
### 🧪 Testing:
|
||||
|
||||
Để test authentication flow:
|
||||
To test authentication flow:
|
||||
|
||||
1. **Tạo file `.env`**:
|
||||
1. **Create `.env` file**:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2. **Ensure backend đang chạy**:
|
||||
2. **Ensure backend is running**:
|
||||
```bash
|
||||
cd server
|
||||
npm run dev
|
||||
```
|
||||
|
||||
3. **Chạy frontend**:
|
||||
3. **Run frontend**:
|
||||
```bash
|
||||
cd client
|
||||
npm run dev
|
||||
```
|
||||
|
||||
4. **Test flow**:
|
||||
- Truy cập `/register` → Đăng ký tài khoản
|
||||
- Truy cập `/login` → Đăng nhập
|
||||
- Truy cập `/dashboard` → Xem dashboard (protected)
|
||||
- Click logout → Xóa session
|
||||
- Reload page → Auth state được khôi phục
|
||||
- Access `/register` → Register account
|
||||
- Access `/login` → Login
|
||||
- Access `/dashboard` → View dashboard (protected)
|
||||
- Click logout → Clear session
|
||||
- Reload page → Auth state restored
|
||||
|
||||
### 🚀 Next Steps:
|
||||
|
||||
**Chức năng 4: Form Login**
|
||||
- Tạo LoginPage với React Hook Form + Yup
|
||||
- Tích hợp với useAuthStore
|
||||
**Function 4: Login Form**
|
||||
- Create LoginPage with React Hook Form + Yup
|
||||
- Integrate with useAuthStore
|
||||
- UX enhancements (loading, show/hide password, remember me)
|
||||
|
||||
**Chức năng 5: Form Register**
|
||||
- Tạo RegisterPage với validation
|
||||
- Tích hợp với useAuthStore
|
||||
**Function 5: Register Form**
|
||||
- Create RegisterPage with validation
|
||||
- Integrate with useAuthStore
|
||||
|
||||
**Chức năng 6-7: Password Reset Flow**
|
||||
**Function 6-7: Password Reset Flow**
|
||||
- ForgotPasswordPage
|
||||
- ResetPasswordPage
|
||||
|
||||
@@ -295,11 +295,11 @@ interface UserInfo {
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Kết quả đạt được:
|
||||
### ✅ Results Achieved:
|
||||
|
||||
1. ✅ Toàn bộ thông tin user được quản lý tập trung
|
||||
2. ✅ Duy trì đăng nhập sau khi reload trang
|
||||
3. ✅ Dễ dàng truy cập userInfo trong mọi component
|
||||
1. ✅ All user information managed centrally
|
||||
2. ✅ Maintain login after page reload
|
||||
3. ✅ Easy access to userInfo in any component
|
||||
4. ✅ Auto token management
|
||||
5. ✅ Type-safe với TypeScript
|
||||
6. ✅ Clean code, dễ maintain
|
||||
5. ✅ Type-safe with TypeScript
|
||||
6. ✅ Clean code, easy to maintain
|
||||
|
||||
Reference in New Issue
Block a user