Skip to content

Tổng quan hệ thống eKYC

Mục tiêu bài học

Sau bài học này, bạn sẽ:

  • Hiểu được tổng thể kiến trúc eKYC trong portal-client
  • Nắm được flow dữ liệu giữa frontend, backend và các service bên ngoài
  • Biết các công nghệ chính được sử dụng
  • Hiểu vai trò của từng component trong hệ thống

Giới thiệu

Hệ thống eKYC (electronic Know Your Customer) trong portal-client cho phép người dùng xác thực danh tính trực tuyến bằng cách:

  1. Chụp ảnh CCCD/CMND (mặt trước và sau)
  2. OCR tự động đọc thông tin từ ảnh
  3. Chụp ảnh khuôn mặt với face liveness detection
  4. So sánh khuôn mặt với ảnh trên CCCD
  5. Kiểm tra và cập nhật thông tin địa chỉ theo đơn vị hành chính mới

Kiến trúc tổng thể

┌─────────────────────────────────────────────────────────────┐
│                     Frontend (Vue 3)                         │
│  ┌────────────┐  ┌────────────┐  ┌────────────────────────┐ │
│  │  Camera    │  │  MediaPipe │  │   EkycSettingEnhanced  │ │
│  │  Module    │──│  FaceMesh  │──│   (Main Component)     │ │
│  └────────────┘  └────────────┘  └────────────────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
                           │ HTTP/HTTPS
                    ┌──────┴──────┐
                    │             │
        ┌───────────▼───┐   ┌────▼─────────────┐
        │ portal-server │   │  External APIs   │
        │  (Backend)    │   │  - sso.inet.vn   │
        │               │   │  - inet.vn       │
        │ - EkycService │   └──────────────────┘
        │ - WardService │
        │ - Customer    │
        └───────────────┘

Stack công nghệ

Frontend

  • Vue 3 (Composition API với <script setup>): Framework chính
  • TypeScript: An toàn kiểu và trải nghiệm developer
  • Pinia: Quản lý trạng thái (lưu trữ các bước, dữ liệu)
  • Ant Design Vue: Component UI (button, modal, select, ...)
  • @mediapipe/face_mesh: Phát hiện khuôn mặt và liveness
  • i18n: Đa ngôn ngữ (Vi/En)
  • Vite: Công cụ build và dev server

Backend

  • Express.js: Web framework
  • Axios: HTTP client cho các API bên ngoài
  • Mongoose: ORM MongoDB
  • Services tùy chỉnh: EkycService, WardService, CustomerService

Dịch vụ bên ngoài

  • sso.inet.vn: API kiểm tra địa chỉ mới (check2fa, tra cứu ward)
  • inet.vn: API OCR và xác thực khuôn mặt
  • MediaPipe CDN: Models WASM cho phát hiện khuôn mặt

Flow hoạt động cơ bản

typescript
// Định nghĩa các step trong flow eKYC
type EkycStep = "preparation" | "front" | "back" | "face" | "review";

// State quản lý flow
const currentStep = ref<EkycStep>("preparation");
const frontImage = reactive({ path: "", file: null });
const backImage = reactive({ path: "", file: null });
const faceImage = reactive({ path: "", file: null });

// OCR data từ backend
const frontOcrData = ref<any>(null);
const backOcrData = ref<any>(null);

// Face verification result
const faceVerificationData = ref<any>(null);

Quy trình 5 bước

1. Preparation (Chuẩn bị)

  • Hiển thị thông tin bảo mật
  • Hướng dẫn người dùng chuẩn bị
  • Tùy chọn eKYC trên thiết bị khác (QR code)

2. Front Card (Chụp mặt trước CCCD)

typescript
async function handleFrontCardImage(imageData: string) {
  frontImage.path = imageData;

  // Gọi OCR backend
  const result = await ekycService.ocrFront(imageData);

  if (result.status === "success") {
    frontOcrData.value = result.data;
    // Tự động chuyển sang bước tiếp theo
    goToStep("back");
  }
}

3. Back Card (Chụp mặt sau CCCD)

typescript
async function handleBackCardImage(imageData: string) {
  backImage.path = imageData;

  const result = await ekycService.ocrBack(imageData);

  if (result.status === "success") {
    backOcrData.value = result.data;
    goToStep("face");
  }
}

4. Face Liveness (Chụp khuôn mặt)

typescript
async function handleFaceImage(imageData: string) {
  faceImage.path = imageData;

  // Backend sẽ so sánh với frontImage
  const result = await ekycService.verifyFace({
    frontImage: frontImage.file,
    faceImage: imageData,
  });

  faceVerificationData.value = result;
  goToStep("review");
}

5. Review & Submit (Xem lại và xác nhận)

  • Hiển thị tất cả dữ liệu OCR
  • Hiển thị kết quả xác thực khuôn mặt
  • Kiểm tra địa chỉ (check2fa)
  • Tìm ward mới nếu cần
  • Gửi cuối cùng

Điểm mạnh của kiến trúc

1. Tách biệt mối quan tâm (Separation of Concerns)

  • Logic camera tách riêng vào components
  • MediaPipe được bọc trong class riêng
  • Logic nghiệp vụ ở component chính
  • Gọi API tập trung trong services

2. Tăng cường dần (Progressive Enhancement)

  • Mỗi bước độc lập, có thể quay lại
  • OCR timeout → dự phòng (fallback) sang xác thực thủ công
  • Ward không tìm thấy → cho phép nhập tay

3. Trải nghiệm người dùng

  • Phản hồi thời gian thực (xem trước camera, trạng thái phát hiện khuôn mặt)
  • Trạng thái tải rõ ràng
  • Xử lý lỗi chi tiết
  • Đa ngôn ngữ

Thách thức kỹ thuật

1. Tích hợp MediaPipe

  • Kích thước module WASM lớn (~7MB)
  • Cần tách biệt khỏi Vue reactivity (vấn đề proxy)
  • Build production phức tạp (vấn đề tối ưu hóa)

2. Truy cập Camera

  • Xử lý quyền
  • Hỗ trợ nhiều thiết bị
  • Quản lý stream và dọn dẹp

3. Quản lý trạng thái

  • 5 bước với nhiều trạng thái phụ thuộc lẫn nhau
  • Xử lý timeout OCR
  • Khôi phục lỗi

4. Hiệu năng

  • Tải ảnh lớn
  • Phát hiện khuôn mặt thời gian thực (60fps)
  • Tối ưu hóa kích thước gói

Tổng kết

Hệ thống eKYC được thiết kế với kiến trúc:

  • Module hóa: Mỗi phần có trách nhiệm rõ ràng
  • Khả năng phục hồi: Xử lý lỗi và dự phòng tốt
  • Thân thiện người dùng: UX mượt mà, phản hồi rõ ràng
  • Có thể mở rộng: Dễ bổ sung thêm các bước hoặc xác thực

Ở các bài học tiếp theo, chúng ta sẽ đi sâu vào từng phần cụ thể với các ví dụ code chi tiết.

Bài học tiếp theo

Chi tiết từng bước trong flow eKYC

Internal documentation for iNET Portal