Hướng Dẫn Sử Dụng OTP Để Xác Thực Email Trong Flutter/Dart Với Shared Hosting

Hướng Dẫn Sử Dụng OTP Để Xác Thực Email Trong Flutter/Dart Với Shared Hosting

·

5 min read

Giới Thiệu

Trong ứng dụng Flutter, khi cần xác thực Email thông qua OTP, chúng ta có nhiều cách để đạt được điều này, chẳng hạn như:

  • Gửi OTP trực tiếp từ trong ứng dụng Flutter. Cách này sẽ không an toàn vì rất dễ để lộ cấu hình của email.

  • Gửi OTP thông qua API gọi đến Server, Server sẽ chịu trách nhiệm tạo mã OTP và gửi đến email của người dùng. Ở cách này chúng ta có hai trường hơp:

    • OTP khi người dùng nhập từ Email sẽ được xác thực lại ở Server, với cách này thì chúng ta cần lưu trữ Email ở Server. Do đó với cách này, chúng ta cần cấu hình nhiều hơn để sử dụng được và có thể ảnh hưởng đến chính sách bảo mật nếu không được thiết lập cẩn thận.

    • OTP khi người dùng nhập từ Email sẽ được xác thực ở phía Client. Với cách này thì Server chỉ thực hiện yêu cầu gửi OTP đến email người dùng, đồng thời gửi OTP đến ứng dụng và ứng dụng sẽ chịu trách nhiệm xác thực OTP khi người dùng nhập mã. Đây cũng chính là cách mình sẽ hướng dẫn ở trong bài viết này.

Hiện nay, Shared Hosting có giá rất rẻ và rất phổ biến trên thị trường, do đó đây là mục tiêu mà mình hướng đến. Bên cạnh đó, mình chọn ngôn ngữ PHP để thực hiện nhiệm vụ gửi OTP vì đây là ngôn ngữ rất lưu động, có thể sử dụng bất kỳ đâu ở Shared Hosting mà không cần cấu hình gì thêm (Javascript được hỗ trợ nhưng phải sử dụng với Nodejs và phải cấu hình Shared Hosting để chạy được ứng dụng Nodejs).

Package được đề cập đến là auth_email, mình sẽ hướng dẫn cụ thể hơn ở bài viết này.

Cấu Hình Và Sử Dụng

Server

Ở phía Server, package sử dụng PHP làm ngôn ngữ, đồng thời sử dụng thư viện PHPMailer để gửi email tới người dùng.

Trước tiên, bạn cần tải v0.0.4 về và giải nén, khi đó bạn sẽ nhận được được thư mục có tên src với cấu trúc như sau:

Và đây là nội dung trong file index.php:

// Set the SMTP server to send through
$HOST = 'example.com';
// SMTP username
$USER_NAME = 'auth@example.com';
// SMTP password
$PASSWORD = 'password';
// TCP port to connect to
$PORT = 587;
// Send from
$SEND_FROM = $USER_NAME;

// Tiêu đề mặc định cho Email
$DEFAULT_SUBJECT = 'Verify Email';
// Nội dung mặc định cho Email
$DEFAULT_BODY = 'Please use this OTP to verify your email for the <b>{appName}</b>, do not share this code to anyone: <b>{otp}</b>';
// Độ dài mặc định của OTP
$DEFAULT_OTP_LENGTH = 6;

// Client key ở mã hóa SHA256 (VD: authemailtestkey)
$SERVER_SHA256_KEY = '6955c3a2dbfd121697623896b38f5eb759d2cd503476980e14b9beb0cc036c4d';

// Bảo mật cho ứng dụng của bạn
$ALLOWED_APPS = [
    // Tên ứng dụng. `appName` ở client phải trùng với tên ứng dụng này
    'Auth Email Test' => [
        // Cho phép/Không cho phép ứng dụng sử dụng tiêu đề tùy chỉnh
        'modifiedSubject' => false,
        // Cho phép/Không cho phép ứng dụng sử dụng nội dung tùy chỉnh
        'modifiedBody' => false,
        // Cho phép/Không cho phép ứng dụng sử dụng độ dài OTP tùy chỉnh
        'modifiedOtpLength' => false,
    ],
];

Bạn hãy cấu hình dựa trên thông tin từ nhà cung cấp email, với số lượng ít thì bạn có thể sử dụng Gmail cho việc xác thực này. Mình sẽ có một bài viết cụ thể hơn về cách sử dụng SMTP trong Gmail.

Với $DEFAULT_BODY, {appName}{otp} sẽ được thay thế bởi appName được lấy từ Client và OTP được tự động tạo ở Server.

Server chỉ cho phép ứng dụng có tên trong $ALLOWED_APPS gọi tới để gửi email.

Sau khi cấu hình xong, bạn hãy tải PHPMailer, config.phpindex.php lên Shared Hosting của bạn. Ví dụ nơi bạn tải lên là https://example.com/auth/email để chuẩn bị cho bước tiếp theo.

Như vậy, chúng ta đã hoàn thiện việc cài đặt ở phía Server.

Client

Thêm package vào ứng dụng:

flutter pub add auth_email

Tạo instance mới cho AuthEmail:

final authEmail = AuthEmail(
    // Tên của ứng dụng. Phải có trong `$ALLOWED_APPS` ở server.
    appName: 'Auth Email Test',
    // URL của server.
    server: 'https://example.com/auth/email',
    // Key của server ở dạng thường.
    serverKey: 'authemailtestkey',
    // In log để debug
    isDebug: true,
);

Tiếp theo, OTP sẽ được gửi như sau:

final bool result = await authEmail.sendOTP(
    email: 'exampleclient@gmail.com', 
    subject: 'Xác Thực',
    body: 'Vui lòng sử dụng OTP này để xác thực cho ứng dụng <b>{appName}</b>, không chia sẻ với bất kỳ ai: <b>{otp}</b>',
    otpLength: 6,
);

Lưu ý là bạn chỉ có thể thay đổi subject, bodyotpLength khi cấu hình ở Server cho phép thay đổi những thông tin này.

Và đây là cách để xác thực OTP sau khi người dùng nhập mã từ Email:

final bool isVerified = authEmail.verifyOTP(
    email: 'exampleclient@gmail.com', 
    otp: '<code>'
);

isVerified sẽ trả về true nếu OTP đã nhập đúng và false nếu OTP sai.

Như vậy, bạn đã có thể xác nhận được Email người dùng nhập có là Email khả dụng hay không rồi.

Thông Tin Thêm

Trước khi thực hiện việc gửi OTP, bạn có thể kiểm tra xem Email người dùng có chính xác hay chưa bằng hàm:

final isValid = AuthEmail.isValidEmail('exampleclient@gmail.com');

Kết Thúc

Như vậy, chúng ta đã có thể gửi và xác nhận OTP một cách đơn giản, an toàn trong ứng dụng Flutter (Dart) khi sử dụng Shared Hosting với ngôn ngữ PHP.