System Architecture Design (DESIGN) - User Management
1. Công nghệ sử dụng (Tech Stack)
Tính năng Quản lý người dùng (User Management) được thực hiện tập trung tại backend với các công nghệ chính:
- Framework: Django (Python 3.11). Sử dụng Django REST Framework (DRF) cho việc thiết kế API.
- Authentication: JSON Web Token (JWT) thông qua thư viện djangorestframework-simplejwt thay thế cho Session truyền thống để đáp ứng tính Stateless, hỗ trợ tốt cho IoT và các Client đa nền tảng.
- Security: Mã hóa mật khẩu một chiều sử dụng thuật toán Argon2 (thuật toán được khuyến nghị hiện đại thay cho PBKDF2 mặc định của Django).
- Database: PostgreSQL lưu trữ dữ liệu User, Role và Permission.
- Cache (Optional / Rate Limiting): Redis (đề xuất sử dụng để đếm số lần đăng nhập sai nhằm khóa IP/Tài khoản tạm thời).
2. Phân tích mã nguồn ảnh hưởng
- Mã nguồn xử lý chính:
./MES-Backend(Chiếm 95% khối lượng công việc, bao gồm DB schema, API, Business Logic). - Mã nguồn bị ảnh hưởng gián tiếp:
./MES-Webstream(hoặc Frontend) (Cần cập nhật UI để gắn token JWT vào Header của các API Request, thiết kế trang Login, Quản lý User cho Admin).
3. Workflow chi tiết (User -> BE -> DB)
3.1 Luồng Đăng nhập (Login Flow)
sequenceDiagram
participant Client as User / Browser
participant API as Backend API (Django)
participant Auth as Auth Middleware & JWT
participant DB as PostgreSQL
Client->>API: POST /api/v1/auth/login {username, password}
API->>Auth: Validate Credentials
Auth->>DB: Query User by username
DB-->>Auth: Trả về Hashed Password & is_active
alt is_active == False
Auth-->>API: User deactivated
API-->>Client: 403 Forbidden
else Validate Password (Argon2 Verify)
Auth->>Auth: Generate AccessToken & RefreshToken (Gắn Role Info)
Auth->>DB: Log Login attempt (Success)
API-->>Client: 200 OK + {access_token, refresh_token}
end
3.2 Luồng Xác thực & Phân quyền (Authorization Flow)
sequenceDiagram
participant Client
participant API
participant Middleware as DRF Permission Classes
participant DB
Client->>API: GET /api/v1/production/orders (Header: Bearer Token)
API->>Middleware: Verify JWT Token
Middleware->>Middleware: Decode Token -> Get user_id & roles
alt Token Hết hạn hoặc Invalid
Middleware-->>Client: 401 Unauthorized
else Token Hợp lệ
Middleware->>DB: Kiểm tra quyền (Role matches 'Production.Read'?)
alt Có Quyền
API->>DB: Process Request
DB-->>API: Data
API-->>Client: 200 OK (Data)
else Không có Quyền
Middleware-->>Client: 403 Forbidden (Permission Denied)
end
end
4. Thiết kế Database (Database Schema ERD)
Thiết kế dựa trên mô hình Role-Based Access Control (RBAC):
- Table
users_user(Sử dụng AbstractBaseUser của Django): id(UUID/PK)username(Varchar, Unique, Index)password(Varchar, Hashed)email(Varchar, Unique)full_name(Varchar)is_active(Boolean, Default: True)failed_login_attempts(Integer, Default: 0)locked_until(DateTime, Nullable)last_login(DateTime, Nullable)-
created_at(DateTime) -
Table
users_role: id(Integer/PK)name(Varchar, Unique) e.g., 'Admin', 'Production Manager', 'Worker'-
description(Text) -
Table
users_user_roles(N-N Relationship): user_id(FK -> users_user.id)-
role_id(FK -> users_role.id) -
Table
users_permission: id(Integer/PK)module_name(Varchar) e.g., 'Production', 'Inventory'action_name(Varchar) e.g., 'Create', 'Read', 'Update', 'Delete'-
code(Varchar, Unique) e.g., 'prod_create', 'inv_read' -
Table
users_role_permissions(N-N Relationship): role_id(FK -> users_role.id)-
permission_id(FK -> users_permission.id) -
Table
users_audit_log(System Log): id(BigInt/PK)user_id(FK -> users_user.id, Nullable cho trường hợp chưa login)action(Varchar) e.g., 'LOGIN_SUCCESS', 'LOGIN_FAILED', 'LOGOUT'ip_address(Varchar)timestamp(DateTime)
5. API Contract Giao tiếp chính
5.1 POST /api/v1/auth/login/
- Request:
{ "username": "worker_01", "password": "SecretPassword123" } - Response (200 OK):
{ "access_token": "eyJhbG...", "refresh_token": "def456...", "expires_in": 3600, "user": { "id": "uuid-1234", "full_name": "Nguyen Van A", "roles": ["Worker"] } }
5.2 POST /api/v1/auth/refresh/
- Request:
{ "refresh_token": "def456..." } - Response (200 OK): Trả về cụm
access_tokenvàrefresh_tokenmới.
5.3 POST /api/v1/auth/logout/
- Request: Header Authorization JWT. Body có thể gửi
refresh_tokenđể đưa vào Blacklist (Zombified token). - Response (200 OK):
{ "message": "Logged out successfully" }