Files
pos-system/services/iam-service-net/docs/vi/ARCHITECTURE.md

25 KiB

Kiến Trúc IAM Service

Tài liệu kiến trúc cho IAM Service (Quản lý Danh tính và Truy cập) xây dựng với .NET 10, Duende IdentityServer, và Clean Architecture.

Tổng Quan Kiến Trúc

graph TB
    subgraph "Clients"
        WEB[Web App]
        MOB[Mobile App]
        SVC[Các Services khác]
        SOCIAL[Google/Facebook]
    end
    
    subgraph "Lớp API"
        AUTH[AuthController]
        USR[UsersController]
        TOK[Token Endpoint]
    end
    
    subgraph "Lớp Application - CQRS"
        CMD[Commands]
        QRY[Queries]
        VAL[Validators]
        BHV[Behaviors]
    end
    
    subgraph "Lớp Domain"
        USER[User Aggregate]
        ROLE[Role Aggregate]
        EVT[Domain Events]
    end
    
    subgraph "Infrastructure"
        CTX[Identity DbContext]
        REPO[Repositories]
        IDSERVER[Duende IdentityServer]
        EMAIL[Email Service]
        TOTP[2FA Service]
        OAUTH[Social Login Service]
    end
    
    subgraph "External"
        DB[(PostgreSQL)]
        REDIS[(Redis)]
        SMTP[SMTP Server]
    end
    
    WEB --> AUTH
    MOB --> AUTH
    SVC --> TOK
    SOCIAL --> AUTH
    AUTH --> CMD
    AUTH --> QRY
    USR --> CMD
    USR --> QRY
    TOK --> IDSERVER
    CMD --> VAL
    CMD --> BHV
    CMD --> USER
    QRY --> REPO
    USER --> EVT
    REPO --> CTX
    IDSERVER --> CTX
    CTX --> DB
    CTX --> REDIS
    EMAIL --> SMTP
    OAUTH --> SOCIAL
    
    style AUTH fill:#4a90d9,stroke:#2d5986,color:#fff
    style USER fill:#50c878,stroke:#2d8659,color:#fff
    style DB fill:#ff6b6b,stroke:#c0392b,color:#fff
    style IDSERVER fill:#9b59b6,stroke:#7d3c98,color:#fff
    style EMAIL fill:#e67e22,stroke:#d35400,color:#fff
    style TOTP fill:#1abc9c,stroke:#16a085,color:#fff
    style OAUTH fill:#3498db,stroke:#2980b9,color:#fff

Luồng Xác Thực OAuth2

sequenceDiagram
    participant Client
    participant AuthController
    participant IdentityServer
    participant UserManager
    participant Database
    
    Note over Client,Database: Password Grant Flow (Đăng nhập)
    
    Client->>AuthController: POST /connect/token<br/>grant_type=password
    AuthController->>IdentityServer: Validate Request
    IdentityServer->>UserManager: FindByEmailAsync()
    UserManager->>Database: Query User
    Database-->>UserManager: User Data
    UserManager->>UserManager: CheckPasswordAsync()
    UserManager-->>IdentityServer: User Validated
    IdentityServer->>IdentityServer: Tạo Tokens (JWT)
    IdentityServer-->>AuthController: Token Response
    AuthController-->>Client: access_token + refresh_token
    
    Note over Client,Database: Sử dụng Access Token
    
    Client->>AuthController: GET /api/v1/users/me<br/>Authorization: Bearer {token}
    AuthController->>IdentityServer: Validate JWT
    IdentityServer-->>AuthController: Claims Principal
    AuthController-->>Client: User Data

Các Loại Token và Grant Types

graph LR
    subgraph "Grant Types"
        PWD[Password Grant]
        REF[Refresh Token]
        CC[Client Credentials]
    end
    
    subgraph "Tokens"
        AT[Access Token<br/>15 phút]
        RT[Refresh Token<br/>7 ngày]
    end
    
    subgraph "Use Cases"
        USER[Đăng nhập User]
        RENEW[Làm mới Token]
        S2S[Service-to-Service]
    end
    
    PWD --> AT
    PWD --> RT
    REF --> AT
    CC --> AT
    
    USER --> PWD
    RENEW --> REF
    S2S --> CC
    
    style AT fill:#2ecc71,stroke:#27ae60,color:#fff
    style RT fill:#f39c12,stroke:#d68910,color:#fff
    style CC fill:#9b59b6,stroke:#7d3c98,color:#fff

Domain Model

User Aggregate

classDiagram
    class ApplicationUser {
        +Guid Id
        +string Email
        +string FirstName
        +string LastName
        +UserStatus Status
        +DateTime CreatedAt
        +DateTime? LastLoginAt
        +UpdateProfile(firstName, lastName)
        +Disable()
        +RecordLogin()
    }
    
    class UserStatus {
        <<enumeration>>
        +Active
        +Locked
        +Disabled
        +PendingVerification
    }
    
    class ApplicationRole {
        +Guid Id
        +string Name
        +string Description
    }
    
    ApplicationUser --> UserStatus : có
    ApplicationUser "nhiều" --> "nhiều" ApplicationRole : thuộc về

Database Schema

erDiagram
    AspNetUsers {
        uuid Id PK
        string Email UK
        string PasswordHash
        string FirstName
        string LastName
        int StatusId FK
        datetime CreatedAt
        datetime LastLoginAt
    }
    
    UserStatuses {
        int Id PK
        string Name
    }
    
    AspNetRoles {
        uuid Id PK
        string Name UK
        string Description
    }
    
    AspNetUserRoles {
        uuid UserId PK,FK
        uuid RoleId PK,FK
    }
    
    IdentityServerPersistedGrants {
        uuid Id PK
        string Key UK
        string Type
        string ClientId
        datetime CreationTime
        datetime Expiration
    }
    
    AspNetUsers ||--o{ UserStatuses : có
    AspNetUsers ||--o{ AspNetUserRoles : có
    AspNetRoles ||--o{ AspNetUserRoles : có

Phase 2: Organization & Group Aggregates

classDiagram
    class Organization {
        +Guid Id
        +string Name
        +string Slug
        +Guid? ParentId
        +OrganizationStatus Status
        +Create()
        +Update()
        +Archive()
    }
    
    class Group {
        +Guid Id
        +Guid OrganizationId
        +string Name
        +string Description
        +AddMember()
        +RemoveMember()
    }
    
    class GroupMember {
        +Guid GroupId
        +Guid UserId
        +GroupRole Role
        +DateTime JoinedAt
    }
    
    Organization "1" --> "*" Group : contains
    Group "1" --> "*" GroupMember : has

Phase 3A: Access Request Aggregate

classDiagram
    class AccessRequest {
        +Guid Id
        +Guid RequesterId
        +string ResourceType
        +Guid ResourceId
        +string RequestedPermission
        +AccessRequestStatus Status
        +AccessRequestPriority Priority
        +DateTime DueDate
        +Submit()
        +Approve()
        +Reject()
        +Cancel()
    }
    
    class AccessRequestApprover {
        +Guid RequestId
        +Guid UserId
        +int ApprovalOrder
        +ApproverStatus Status
        +string Comments
        +Approve()
        +Reject()
    }
    
    class AccessRequestStatus {
        <<enumeration>>
        +Draft
        +Pending
        +Approved
        +Rejected
        +Cancelled
        +Expired
    }
    
    AccessRequest "1" --> "*" AccessRequestApprover : has
    AccessRequest --> AccessRequestStatus : has

Phase 3B: Access Review & PAM Aggregates

classDiagram
    class AccessReview {
        +Guid Id
        +string Name
        +Guid OwnerId
        +string Scope
        +AccessReviewStatus Status
        +DateTime DueDate
        +Start()
        +Complete()
        +Cancel()
    }
    
    class AccessReviewItem {
        +Guid Id
        +Guid UserId
        +string ResourceType
        +Guid ResourceId
        +ReviewDecision Decision
        +Certify()
        +Revoke()
    }
    
    class PrivilegedAccessGrant {
        +Guid Id
        +Guid UserId
        +Guid RoleId
        +string ResourceScope
        +PrivilegedAccessStatus Status
        +DateTime StartsAt
        +DateTime ExpiresAt
        +Activate()
        +Revoke()
        +Extend()
    }
    
    AccessReview "1" --> "*" AccessReviewItem : contains

Phase 4A: Audit & Compliance Aggregates

classDiagram
    class AuditLog {
        +Guid Id
        +AuditEventType EventType
        +Guid? ActorId
        +string ResourceType
        +Guid? ResourceId
        +string Action
        +bool Success
        +DateTime Timestamp
        +LoginEvent()
        +AccessGrantedEvent()
    }
    
    class ComplianceReport {
        +Guid Id
        +string Name
        +ComplianceReportType ReportType
        +ComplianceReportStatus Status
        +int TotalChecks
        +int PassedChecks
        +double CompliancePercentage
        +StartGenerating()
        +Complete()
        +Fail()
    }
    
    class ComplianceViolation {
        +Guid Id
        +string Rule
        +ViolationSeverity Severity
        +string Description
        +bool Resolved
        +Resolve()
    }
    
    ComplianceReport "1" --> "*" ComplianceViolation : has

AuditEventType (18 Event Types)

Category Event Types
Authentication Login, Logout, LoginFailed, PasswordChanged, TwoFactorEnabled/Disabled
User Management UserCreated, UserUpdated, UserDeleted, UserLocked/Unlocked
Access Control AccessRequested, AccessGranted, AccessRevoked, AccessDenied, PrivilegedAccessGranted/Revoked
Organization OrganizationCreated/Updated, GroupMemberAdded/Removed
Policy PolicyCreated, PolicyActivated, PolicyDeactivated
Compliance ComplianceReportGenerated, ViolationDetected, ViolationResolved

CQRS Pipeline

sequenceDiagram
    participant Controller
    participant MediatR
    participant LoggingBehavior
    participant ValidatorBehavior
    participant TransactionBehavior
    participant CommandHandler
    participant Repository
    
    Controller->>MediatR: Send(Command)
    MediatR->>LoggingBehavior: Handle
    LoggingBehavior->>ValidatorBehavior: Next()
    ValidatorBehavior->>TransactionBehavior: Next()
    TransactionBehavior->>CommandHandler: Next()
    CommandHandler->>Repository: Save
    Repository-->>CommandHandler: Result
    CommandHandler-->>Controller: Response

Thứ Tự Pipeline Behaviors

Thứ tự Behavior Mục đích
1 LoggingBehavior Ghi log request/response với timing
2 ValidatorBehavior FluentValidation
3 TransactionBehavior Bao database transaction

Kiến Trúc Bảo Mật

graph TD
    subgraph "Authentication"
        JWT[JWT Bearer Tokens]
        RS256[RS256 Signing]
        OIDC[IdentityServer]
        MFA[2FA/TOTP]
        SOCIAL[Social OAuth]
    end
    
    subgraph "Authorization"
        RBAC[Role-Based Access]
        CLAIMS[Claims-Based]
        POLICY[Policy Enforcement]
    end
    
    subgraph "Protection"
        HASH[bcrypt Password Hash]
        HTTPS[HTTPS/TLS]
        CORS[CORS Policy]
        EMAIL[Email Verification]
    end
    
    JWT --> RS256
    RS256 --> OIDC
    RBAC --> CLAIMS
    CLAIMS --> POLICY
    MFA --> JWT
    SOCIAL --> JWT
    
    style JWT fill:#3498db,stroke:#2980b9,color:#fff
    style RBAC fill:#e74c3c,stroke:#c0392b,color:#fff
    style HASH fill:#2ecc71,stroke:#27ae60,color:#fff
    style MFA fill:#9b59b6,stroke:#7d3c98,color:#fff
    style SOCIAL fill:#e67e22,stroke:#d35400,color:#fff

Authorization Policies

Tổng Quan Authorization

IAM Service sử dụng Policy-Based Authorization để phân quyền API endpoints:

graph TB
    subgraph "Request Flow"
        REQ[HTTP Request] --> AUTH[Authentication<br/>JWT Bearer]
        AUTH --> POLICY[Policy Check]
        POLICY --> HANDLER[Authorization Handler]
    end
    
    subgraph "Policies"
        SUPER[RequireSuperAdmin]
        ADMIN[RequireAdmin]
        AUDITOR[RequireAuditor]
        OWNER[OwnerOrAdmin]
    end
    
    subgraph "Roles"
        R_SUPER[SuperAdmin]
        R_ADMIN[Admin]
        R_AUDITOR[Auditor]
        R_USER[User]
    end
    
    HANDLER --> SUPER
    HANDLER --> ADMIN
    HANDLER --> AUDITOR
    HANDLER --> OWNER
    
    SUPER --> R_SUPER
    ADMIN --> R_SUPER
    ADMIN --> R_ADMIN
    AUDITOR --> R_SUPER
    AUDITOR --> R_ADMIN
    AUDITOR --> R_AUDITOR
    OWNER --> R_SUPER
    OWNER --> R_ADMIN
    OWNER --> R_USER
    
    style SUPER fill:#c0392b,stroke:#922b21,color:#fff
    style ADMIN fill:#e74c3c,stroke:#c0392b,color:#fff
    style AUDITOR fill:#9b59b6,stroke:#7d3c98,color:#fff
    style OWNER fill:#3498db,stroke:#2980b9,color:#fff

Bảng Policies

Policy Required Roles Mô tả
RequireSuperAdmin SuperAdmin Quyền cao nhất - PAM, system config
RequireAdmin SuperAdmin, Admin Quản lý users, roles, organizations
RequireAuditor SuperAdmin, Admin, Auditor Xem audit logs, compliance reports
OwnerOrAdmin Admin hoặc chính user User tự quản lý profile

Luồng Authorization

sequenceDiagram
    participant Client
    participant Controller
    participant AuthorizationService
    participant PolicyHandler
    participant ClaimsPrincipal
    
    Client->>Controller: Request với JWT
    Controller->>AuthorizationService: Authorize(Policy)
    AuthorizationService->>PolicyHandler: EvaluatePolicy()
    PolicyHandler->>ClaimsPrincipal: GetRoles()
    ClaimsPrincipal-->>PolicyHandler: ["Admin", "User"]
    
    alt Role Match
        PolicyHandler-->>AuthorizationService: Success
        AuthorizationService-->>Controller: Authorized
        Controller-->>Client: 200 OK
    else Role Not Match
        PolicyHandler-->>AuthorizationService: Fail
        AuthorizationService-->>Controller: Forbidden
        Controller-->>Client: 403 Forbidden
    end

Áp Dụng Theo Controller

Controller Policy Endpoints
UsersController RequireAdmin / OwnerOrAdmin GET /users (Admin), GET/PUT /{id} (Owner or Admin)
RolesController RequireAdmin Tất cả endpoints
OrganizationsController RequireAdmin Tất cả endpoints
GroupsController RequireAdmin Tất cả endpoints
AccessRequestsController RequireAdmin Tất cả endpoints
AccessReviewsController RequireAdmin Tất cả endpoints
PrivilegedAccessController RequireSuperAdmin Tất cả endpoints (nhạy cảm nhất)
AuditController RequireAuditor GET /audit/logs
ComplianceController RequireAuditor Tất cả endpoints
VerificationsController RequireAdmin Tất cả endpoints

Custom Authorization Handler: OwnerOrAdmin

// EN: OwnerOrAdmin allows:
//     1. Admin/SuperAdmin - always allowed
//     2. User accessing their own resource (userId in route matches current user)
// VI: OwnerOrAdmin cho phép:
//     1. Admin/SuperAdmin - luôn được phép
//     2. User truy cập resource của chính mình

public class OwnerOrAdminHandler : AuthorizationHandler<OwnerOrAdminRequirement>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        OwnerOrAdminRequirement requirement)
    {
        // Admin/SuperAdmin always allowed
        if (context.User.IsInRole("Admin") || context.User.IsInRole("SuperAdmin"))
        {
            context.Succeed(requirement);
            return Task.CompletedTask;
        }
        
        // Check if user accessing own resource
        var currentUserId = context.User.FindFirst("sub")?.Value;
        var routeUserId = httpContext.GetRouteValue("id")?.ToString();
        
        if (currentUserId == routeUserId)
        {
            context.Succeed(requirement);
        }
        
        return Task.CompletedTask;
    }
}

Luồng Xác Thực Email

sequenceDiagram
    participant User
    participant AuthController
    participant EmailService
    participant SMTP
    participant Database
    
    Note over User,Database: Gửi Email Xác Thực
    
    User->>AuthController: POST /send-verification-email
    AuthController->>Database: Tạo Token
    Database-->>AuthController: Confirmation Token
    AuthController->>EmailService: SendVerificationEmail()
    EmailService->>SMTP: Gửi Email với Link
    SMTP-->>User: Email với Link Xác Thực
    
    Note over User,Database: Xác Nhận Email
    
    User->>AuthController: POST /confirm-email<br/>(userId, token)
    AuthController->>Database: Kiểm tra Token
    Database-->>AuthController: Token hợp lệ
    AuthController->>Database: Set EmailConfirmed = true
    AuthController-->>User: Email đã xác nhận

Luồng Xác Thực Hai Yếu Tố (2FA)

sequenceDiagram
    participant User
    participant AuthController
    participant TwoFactorService
    participant Database
    participant AuthenticatorApp
    
    Note over User,AuthenticatorApp: Bật 2FA
    
    User->>AuthController: POST /2fa/enable
    AuthController->>TwoFactorService: GenerateSecretKey()
    TwoFactorService-->>AuthController: Secret Key
    AuthController->>TwoFactorService: GenerateQrCode()
    TwoFactorService-->>AuthController: QR Code (Base64)
    AuthController-->>User: Secret + QR Code + Recovery Codes
    User->>AuthenticatorApp: Quét QR Code
    
    Note over User,AuthenticatorApp: Xác Minh & Kích Hoạt
    
    User->>AuthController: POST /2fa/verify (code)
    AuthController->>TwoFactorService: ValidateCode(secret, code)
    TwoFactorService-->>AuthController: Hợp lệ
    AuthController->>Database: Lưu Secret & Bật 2FA
    AuthController-->>User: 2FA đã được bật

Luồng Đăng Nhập Mạng Xã Hội

sequenceDiagram
    participant User
    participant Client
    participant AuthController
    participant OAuthProvider
    participant SocialLoginService
    participant Database
    
    Note over User,Database: OAuth Flow
    
    User->>Client: Click "Đăng nhập với Google"
    Client->>AuthController: GET /external-login/Google
    AuthController->>OAuthProvider: Redirect đến OAuth
    OAuthProvider->>User: Login & Đồng ý
    User->>OAuthProvider: Chấp thuận
    OAuthProvider->>AuthController: GET /external-callback (code)
    AuthController->>SocialLoginService: ProcessExternalLogin()
    SocialLoginService->>Database: Tìm/Tạo User
    Database-->>SocialLoginService: User
    SocialLoginService-->>AuthController: User + Tokens
    AuthController-->>Client: Redirect với tokens

Health Checks

graph TD
    HC[Health Check Endpoints]
    HC -->|/health/live| L[Liveness Probe]
    HC -->|/health/ready| R[Readiness Probe]
    HC -->|/health| F[Full Status]
    
    R --> PG[(PostgreSQL Check)]
    R --> RD[(Redis Check)]
    
    style HC fill:#3498db,stroke:#2980b9,color:#fff
    style L fill:#2ecc71,stroke:#27ae60,color:#fff
    style R fill:#f39c12,stroke:#d68910,color:#fff

Kiến Trúc Deployment

Docker Compose (Local/Development)

services:
  iam-service:
    build: .
    ports: ["5001:8080"]
    depends_on:
      - postgres
      - redis
    environment:
      - DATABASE_URL=Host=postgres;...
      
  postgres:
    image: postgres:16-alpine
    
  redis:
    image: redis:7-alpine

Kubernetes (Production)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iam-service
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: iam-service
        image: goodgo/iam-service:latest
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /health/live
            port: 8080
        readinessProbe:
          httpGet:
            path: /health/ready
            port: 8080

Xử Lý Lỗi

Phân Cấp Exception

Exception
└── DomainException
    └── (Custom domain exceptions)

Problem Details (RFC 7807)

Tất cả lỗi trả về định dạng Problem Details:

{
  "type": "https://tools.ietf.org/html/rfc7807",
  "title": "Lỗi Validation",
  "status": 400,
  "detail": "Một hoặc nhiều lỗi validation đã xảy ra.",
  "errors": {
    "Email": ["Email là bắt buộc"]
  }
}

Kiến Trúc Distributed Caching

Tổng Quan Caching

graph TB
    subgraph "Application"
        SVC[Services]
        CACHE[ICacheService]
    end
    
    subgraph "Tầng Caching"
        REDIS[(Redis Server)]
        TOKEN[Token Cache]
        SESSION[Session Cache]
        DATA[Data Cache]
    end
    
    SVC --> CACHE
    CACHE --> REDIS
    REDIS --> TOKEN
    REDIS --> SESSION
    REDIS --> DATA
    
    style CACHE fill:#e74c3c,stroke:#c0392b,color:#fff
    style REDIS fill:#d35400,stroke:#a04000,color:#fff
    style TOKEN fill:#9b59b6,stroke:#7d3c98,color:#fff
    style SESSION fill:#3498db,stroke:#2980b9,color:#fff
    style DATA fill:#2ecc71,stroke:#27ae60,color:#fff

ICacheService Interface

Service implement interface ICacheService cho distributed caching:

Method Mục Đích
GetAsync<T> Lấy item từ cache theo key
SetAsync<T> Lưu item với TTL tùy chọn
RemoveAsync Xóa item từ cache
ExistsAsync Kiểm tra key tồn tại
GetOrSetAsync<T> Pattern cache-aside
BlacklistAsync Thêm vào blacklist token
IsBlacklistedAsync Kiểm tra blacklist token

Chiến Lược Token Caching

sequenceDiagram
    participant Client
    participant AuthController
    participant CacheService
    participant Redis
    participant Database
    
    Note over Client,Database: Validate Token với Cache
    
    Client->>AuthController: Request với JWT
    AuthController->>CacheService: IsBlacklistedAsync(tokenId)
    CacheService->>Redis: GET blacklist:token:{id}
    Redis-->>CacheService: null (không bị blacklist)
    CacheService-->>AuthController: false
    AuthController->>AuthController: Validate JWT Claims
    AuthController-->>Client: Response
    
    Note over Client,Database: Thu Hồi Token (Logout)
    
    Client->>AuthController: POST /logout
    AuthController->>CacheService: BlacklistAsync(tokenId, 7 ngày)
    CacheService->>Redis: SETEX blacklist:token:{id} 604800 "1"
    Redis-->>CacheService: OK
    AuthController-->>Client: 200 OK

Token Cache Keys

Mẫu Key Mục Đích TTL
blacklist:token:{tokenId} Tokens đã thu hồi Thời gian còn lại của token
blacklist:refresh:{tokenId} Refresh tokens đã thu hồi 7 ngày
user:{userId}:tokens Tokens đang hoạt động của user 15 phút

Chiến Lược Session Caching

graph LR
    subgraph "Session Data"
        UID[User ID]
        ROLES[User Roles]
        PERMS[Permissions]
        CLAIMS[Claims]
    end
    
    subgraph "Cache Keys"
        K1[session:{userId}]
        K2[user:{userId}:roles]
        K3[user:{userId}:permissions]
    end
    
    UID --> K1
    ROLES --> K2
    PERMS --> K3
    
    style K1 fill:#3498db,stroke:#2980b9,color:#fff
    style K2 fill:#9b59b6,stroke:#7d3c98,color:#fff
    style K3 fill:#2ecc71,stroke:#27ae60,color:#fff

Session Cache Keys

Mẫu Key Mục Đích TTL
session:{userId} Dữ liệu session user 30 phút
user:{userId}:roles Cached user roles 15 phút
user:{userId}:permissions Computed permissions 15 phút
user:{userId}:profile Dữ liệu profile user 10 phút

Pattern Cache-Aside

sequenceDiagram
    participant Service
    participant CacheService
    participant Redis
    participant Database
    
    Service->>CacheService: GetOrSetAsync(key, factory)
    CacheService->>Redis: GET key
    
    alt Cache Hit
        Redis-->>CacheService: dữ liệu cached
        CacheService-->>Service: trả về dữ liệu
    else Cache Miss
        Redis-->>CacheService: null
        CacheService->>Database: factory() - lấy dữ liệu
        Database-->>CacheService: dữ liệu
        CacheService->>Redis: SETEX key ttl data
        CacheService-->>Service: trả về dữ liệu
    end

Chiến Lược Invalidation Cache

Chiến Lược Khi Nào Sử Dụng Implementation
Time-based (TTL) Dữ liệu chung SetAsync(..., TimeSpan.FromMinutes(15))
Event-based Cập nhật user Xóa cache khi có event cập nhật
Pattern-based Invalidation hàng loạt RemoveByPatternAsync("user:*")

Cân Nhắc Hiệu Năng

  1. Connection Pooling: EF Core với Npgsql resilience
  2. Token Caching: Redis cho token validation và blacklist
  3. Session Caching: User sessions và permissions được cache
  4. Async Operations: Tất cả I/O operations đều async
  5. Database Indexes: Cấu hình trong EntityConfigurations
  6. Cache-Aside Pattern: Giảm tải database cho các truy vấn thường xuyên

Tài Liệu Tham Khảo