Cách xác thực người dùng bằng QR Code

Vừa rồi Facebook đã cho ra mắt tính năng đăng nhập trên website bằng cách sử dụng FB app quét mã QR. Mình thấy tính năng khá hay mà không biết vì lý do gì lại không triển khai rộng rãi, chắc là lý do bảo mật, hiệu suất.

Đăng nhập FB bằng mobile

Nhân tiện đây mình sẽ chia sẻ với các đồng dâm cách thực thi hệ thống dùng QR để xác thực, thanh toán và nhiều ứng dụng khác.

Hình ảnh sau đây cách cũng không còn xa lạ với những anh em hay dùng ứng dụng chat s__ à nhầm chat chít, thanh toán trực tuyến =))

Đăng nhập Zalo

Thanh toán bằng Vietcombank quét QR của VNPay


Thanh toán online với MoMo

I. Mô hình hoạt động



QR Code Works


  1. Đầu tiên, website hoặc desktop application sẽ yêu cầu server tạo ra một mã QR. Mã QR này chứa những thông tin cần thiết để tạo ra một session.
  2. Client hiện thị QR Code cho người dùng, đồng thời lắng nghe kết quả quét mã QR từ phía Server 2'.
  3. User sử dụng mobile app quét mã
  4. Mobile app sẽ đọc mã QRCode, khởi tạo dữ liệu và submit dữ liệu lên server.
  5. Server xử lý thông tin trả kết quả cho mobile đồng thời cập nhập thông cho 2'.
  6. Client xử lý những bước tiếp theo sau khi có kết quả xác thực.

II. Cách thực thi

Nhìn vào sơ đồ trên sẽ dễ dàng nhận ra rằng có rất nhiều cách để thực thi hệ thống trên.
Điểm mấu chốt ở hệ thống sẽ là làm thế nào để:

  • Mobile app tương tác được với QR: Read, Parsing.
  • Website nhận kết quả xác thực từ phía Mobile

Đây là cách mình và team MoMo Payment đã thực thi (đây cũng cách này đơn giản nhất và theo mình là dễ tiếp cận nhất, vì trên thực tế bên mình phải xử lý nhiều hơn để đảm bảo bảo mật, hiệu suất, v,v...)

1. Phía server:

  • QR code: Tạo ra mã QR chứa data là một chuỗi JSON
    {
        "requestId": "1531032217726",
        "sessionId": "fb2e77d.47a0472900504cb3ab4a1f626d174d2x2",
        "requestTime":"1531032217726"
    }
    
  • Xây dựng API để client (website/desktop) lấy kết quả xác thực sau khi user quét mã QR
  • Xây dựng API để Mobile app submit data bao gồm thông tin liên quan tới QR Code, thông tin user

2. Phía client (Website/Desktop)

  • QrCode được hiện thị từ chuỗi base64

    <img src="data:image/png;base64, ....." alt="Day la cai QR Code" />
    

    Hoặc

     <img src="https://daylacaidomain.com/login/dynamic-qrcode.png" alt="Day la cai QR Code" />
    
  • Listen event - Lắng nghe kết quả (bước 2')
    Mình dùng Ajax cứ mỗi năm giây gọi lên server để kiểm tra trạng thái xác thực.

    function executeQuery() {
        $.ajax({
            url: 'api_get_result_authenticaton',
            method: 'POST',
            data: {},
            success: function(data) {
                // Xử lý kết quả
                if (data.statusCode >= 0) {
                    // Đăng nhập thành công; chuyển sang trang mới
                    window.location.href = data.url;
                } else {
                    // Nếu chưa đăng nhập thì thử lại
                    if (retry > 0)
                        setTimeout(executeQuery, 5000); // 5s gọi lên server 1 lần
    
                }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                console.error("Error throw: ", errorThrown);
            }
        });
    }
    

Ở đây các bạn có thể dùng websocket,v.v....

3. Phía Mobible app

  • Xây dựng bộ parsing data từ mã QR, có nghĩa là app đọc được dữ liệu từ QR và theo cấu trúc mà server quy định.
  • Đính kèm nhưng thông tin của user vào với data của QR để hoàn tất login trên web

Hi vọng bài này sẽ giúp mọi người hình dung cách thức hoạt động của hệ thống này :))

Sắp tới mình sẽ viết một bài về những điều lưu ý khi làm việc hệ thống này: concurrent, caching, expire, security .