Đăng Nhập Người Dùng

Mô Tả Tổng Quan

Tính năng đăng nhập người dùng cho phép người dùng đã đăng ký xác thực vào hệ thống bằng email và Firebase token. Hệ thống xác minh Firebase token, kiểm tra trạng thái người dùng và thành viên nhóm, sau đó tạo session và trả về authentication cookies. Hệ thống cũng theo dõi trạng thái đăng nhập lần đầu để cung cấp trải nghiệm người dùng phù hợp.

API: User Login API

Biểu Đồ Hoạt Động

flowchart TD
    A[Client gửi yêu cầu đăng nhập] --> B[Xác thực dữ liệu yêu cầu]
    B --> C{Dữ liệu hợp lệ?}
    C -->|Không| D[Trả về lỗi xác thực]
    C -->|Có| E[Xác minh Firebase token]
    E --> F{Token hợp lệ?}
    F -->|Không| G[Trả về lỗi xác thực]
    F -->|Có| H[Tìm user theo UID]
    H --> I{User tồn tại?}
    I -->|Không| J[Trả về lỗi user không tồn tại]
    I -->|Có| K[Kiểm tra trạng thái user]
    K --> L{User hoạt động?}
    L -->|Không| M[Trả về lỗi user không hoạt động]
    L -->|Có| N[Kiểm tra thành viên nhóm]
    N --> O{User trong nhóm?}
    O -->|Không| P[Trả về lỗi không có nhóm]
    O -->|Có| Q[Cập nhật is_first_login]
    Q --> R[Tạo authentication cookies]
    R --> S[Trả về phản hồi thành công]
    
    style A fill:#e1f5fe
    style S fill:#c8e6c9
    style D fill:#ffcdd2
    style G fill:#ffcdd2
    style J fill:#ffcdd2
    style M fill:#ffcdd2
    style P fill:#ffcdd2

Biểu Đồ Tuần Tự

Đăng Nhập Thành Công

sequenceDiagram
    participant Client
    participant LoginController
    participant AuthService
    participant Firebase
    participant Database
    
    Note over Client,Database: Luồng Đăng Nhập Thành Công
    
    rect rgb(200, 255, 200)
    Note right of Client: Happy Case Flow
    
    Client->>LoginController: POST /api/v1/general/auth/login
    Note over Client,LoginController: {email} + firebase-token header
    
    rect rgb(200, 230, 255)
    Note right of LoginController: Xác Thực Đầu Vào
    LoginController->>LoginController: Xác thực yêu cầu
    end
    
    rect rgb(200, 255, 255)
    Note right of LoginController: Logic Nghiệp Vụ
    LoginController->>AuthService: login(email, firebaseToken)
    
    AuthService->>Firebase: verifyIdToken(firebaseToken)
    Firebase-->>AuthService: Thông tin user (uid, email, provider)
    
    AuthService->>Database: Tìm user theo UID
    Database-->>AuthService: Dữ liệu user + is_first_login
    
    AuthService->>Database: Kiểm tra trạng thái user & nhóm
    Database-->>AuthService: Thông tin thành viên nhóm
    
    AuthService->>Database: Cập nhật is_first_login = false
    Database-->>AuthService: Cập nhật thành công
    end
    
    rect rgb(230, 200, 255)
    Note right of AuthService: Tạo Phiên
    AuthService->>AuthService: createAuthCookieByUser()
    AuthService-->>LoginController: Dữ liệu user + cookies
    end
    
    LoginController->>Client: 200 OK + Set-Cookie headers
    end
    
    rect rgb(255, 200, 200)
    Note right of Client: Error Handling
    rect rgb(255, 230, 230)
    alt Validation Error
        LoginController->>Client: 422 Validation Error
    else Invalid Token
        Firebase-->>AuthService: Token verification failed
        AuthService-->>LoginController: Authentication failed
        LoginController->>Client: 401 Unauthorized
    else User Not Found
        Database-->>AuthService: User not found
        AuthService-->>LoginController: User not found
        LoginController->>Client: 404 User Not Found
    else User Inactive
        Database-->>AuthService: User inactive
        AuthService-->>LoginController: User status error
        LoginController->>Client: 403 Forbidden
    else No Group Membership
        Database-->>AuthService: No group membership
        AuthService-->>LoginController: Group error
        LoginController->>Client: 403 Forbidden
    end
    end
    end

Đăng Nhập Thất Bại

sequenceDiagram
    participant Client
    participant LoginController
    participant AuthService
    participant Firebase
    
    Note over Client,Firebase: Luồng Đăng Nhập Thất Bại
    
    rect rgb(255, 200, 200)
    Note right of Client: Error Flow
    
    Client->>LoginController: POST /api/v1/general/auth/login
    Note over Client,LoginController: Token không hợp lệ hoặc hết hạn
    
    LoginController->>LoginController: Xác thực yêu cầu
    LoginController->>AuthService: login(email, firebaseToken)
    
    AuthService->>Firebase: verifyIdToken(firebaseToken)
    Firebase-->>AuthService: Lỗi token không hợp lệ
    
    AuthService-->>LoginController: Xác thực thất bại
    LoginController->>Client: 401 Unauthorized
    end

Headers Chi Tiết

Request Headers

Header Bắt Buộc Mô Tả Ví Dụ
firebase-token Firebase ID token từ client eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Cookies Chi Tiết

Authentication Cookies

1. Auth API Token Cookie

Set-Cookie: Trend-Viewer_auth_api_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...; 
HttpOnly; 
Secure; 
SameSite=Lax; 

Thuộc tính:

  • Name: Trend-Viewer_auth_api_token (trong đó {app_name} là tên ứng dụng từ config)
  • Value: JWT token được mã hóa
  • HttpOnly: true (không thể truy cập qua JavaScript)
  • Secure: true (chỉ gửi qua HTTPS)
  • SameSite: Lax (bảo mật CSRF)

2. Logged In Status Cookie

Set-Cookie: Trend-Viewer_is_logged_in=true; 
HttpOnly; 
Secure; 
SameSite=Lax; 

Thuộc tính:

  • Name: Trend-Viewer_is_logged_in
  • Value: true
  • HttpOnly: true
  • Secure: `true**
  • SameSite: Lax

Các Bước Chi Tiết

Bước 1: Xác Thực Yêu Cầu

Đầu vào:

  • Địa chỉ email từ body yêu cầu (bắt buộc)
  • Firebase token từ header firebase-token (bắt buộc)

Validation Rules:

'email' => 'required|email|max:255',
'firebase-token' => 'required|string|min:100'

Kiểm tra:

  • Email format hợp lệ
  • Firebase token không rỗng và đủ độ dài

Bước 2: Xác Minh Firebase Token

Quy trình:

  • Trích xuất Firebase ID token từ header firebase-token
  • Gửi token đến dịch vụ Firebase Authentication
  • Xác minh tính xác thực và thời hạn token
  • Trích xuất thông tin user (Firebase):
    • uid: Firebase User ID (duy nhất)
    • email: Email đã xác minh
    • provider: Nhà cung cấp xác thực (google, password, etc.)
    • email_verified: Trạng thái xác minh email

Error Handling:

  • Token không hợp lệ: 401 Unauthorized
  • Token hết hạn: 401 Unauthorized

Bước 3: Tìm Kiếm User

Dữ liệu User được truy xuất:

  • Basic Info: ID, tên, email, trạng thái
  • Firebase Info: UID, email_verified_at
  • Account Info: is_first_login, created_at, updated_at
  • Group Info: Thành viên nhóm, vai trò nhóm
  • Payment Info: payment_provider_customer_id

Bước 4: Kiểm Tra Thành Viên Nhóm

Yêu cầu:

  • User phải thuộc ít nhất một nhóm hoạt động
  • Kiểm tra groupMember() relationship tồn tại
  • Error: Nếu không có nhóm → 401 Unauthorized với message "ログイン情報が正しくありません。"

Bước 5: Kiểm Tra Trạng Thái Nhóm

Kiểm tra Admin Group:

  • Nếu user là admin, kiểm tra group.status
  • Error: Nếu nhóm admin inactive → 401 Unauthorized với message "この事業者が無効になっています。管理者に連絡してください。"

Kiểm tra Group Member:

  • Kiểm tra groupMember.group.status
  • Error: Nếu nhóm member inactive → 401 Unauthorized với message "この事業者が無効になっています。管理者に連絡してください。"

Bước 6: Tạo Session và Cookies

Dữ liệu Session được lưu trữ:

  • User Info: User ID, email, name
  • Authentication: JWT token, refresh token
  • Security: Session ID, CSRF token

Cookies được tạo:

  • auth_token: JWT token
  • logged_in: Trạng thái đăng nhập
  • user_session: Session identifier

Bước 7: Trả Về Response

Success Response:

  • Status: 200 OK
  • Body: UserResource với đầy đủ thông tin user
  • Headers: Set-Cookie cho authentication cookies
  • Message: "ログインサクセス"

Error Response:

  • Status: 401 Unauthorized cho hầu hết lỗi
  • Body: {"status": false, "message": "error message"}

is_first_login Flag

  • Mục đích: Xác định người dùng đăng nhập lần đầu
  • Logic:
    • true: Lần đầu đăng nhập, hiển thị Modal welcome
    • false: Đã đăng nhập trước đó
  • Cập nhật: Tự động chuyển từ true sang false sau lần đăng nhập đầu tiên

Group Status Validation

  • Member Group Check: Kiểm tra group.status cho tất cả users general
  • Error Handling: Cả hai trường hợp đều trả về 401 Unauthorized với message tiếng Nhật
  • Business Logic: User không thể đăng nhập nếu nhóm bị vô hiệu hóa

Session Management

  • Duration: 24 giờ (có thể cấu hình)
  • Refresh: Tự động refresh khi user active
  • Multiple Sessions: Hỗ trợ đăng nhập trên nhiều thiết bị
  • Force Logout: Admin có thể force logout user

Security Features

  • CSRF Protection: SameSite cookie attribute
  • XSS Prevention: HttpOnly cookies
  • Man-in-the-Middle: Secure flag cho HTTPS
  • Session Hijacking: IP và User-Agent validation