Xác thực bằng Firebase bằng đường liên kết email

Bạn có thể sử dụng tính năng Xác thực Firebase để đăng nhập người dùng bằng cách gửi email cho họ chứa một liên kết mà họ có thể nhấp vào để đăng nhập. Trong quá trình này, thông tin địa chỉ email cũng được xác minh.

Có rất nhiều lợi ích khi đăng nhập qua email:

  • Quy trình đăng ký và đăng nhập ít phiền hà.
  • Giảm nguy cơ dùng lại mật khẩu trên các ứng dụng, từ đó làm giảm khả năng bảo mật thậm chí là những mật khẩu được chọn kỹ.
  • Khả năng xác thực người dùng trong khi cũng xác minh rằng người dùng là chủ sở hữu hợp pháp của một địa chỉ email.
  • Người dùng chỉ cần có một tài khoản email có thể truy cập để đăng nhập. Không có quyền sở hữu đối với số điện thoại hoặc tài khoản mạng xã hội.
  • Người dùng có thể đăng nhập an toàn mà không cần cung cấp (hoặc ghi nhớ) mã mật khẩu. Mật khẩu này có thể rườm rà trên thiết bị di động.
  • Một người dùng hiện tại từng đăng nhập bằng mã nhận dạng email (mật khẩu) hoặc liên kết) có thể được nâng cấp để đăng nhập chỉ bằng email. Ví dụ: một người dùng quên mật khẩu của mình vẫn có thể đăng nhập mà không cần đặt lại mật khẩu của họ.

Trước khi bắt đầu

  1. Làm theo các bước trong hướng dẫn Bắt đầu nếu bạn chưa làm việc này.

  2. Bật tính năng đăng nhập bằng đường liên kết email cho dự án Firebase của bạn.

    Để đăng nhập cho người dùng bằng đường liên kết qua email, trước tiên bạn phải bật Nhà cung cấp dịch vụ email và phương pháp đăng nhập bằng đường liên kết qua email cho dự án Firebase của bạn:

    1. Trong bảng điều khiển của Firebase, hãy mở phần Xác thực.
    2. Trên thẻ Phương thức đăng nhập, hãy bật nhà cung cấp Email/Mật khẩu. Lưu ý rằng bạn phải bật tính năng đăng nhập bằng email/mật khẩu để sử dụng đường liên kết email đăng nhập.
    3. Cũng trong phần này, hãy bật tuỳ chọn Đường liên kết qua email (đăng nhập không cần mật khẩu) đăng nhập.
    4. Nhấp vào Lưu.

Để bắt đầu quy trình xác thực, hãy trình bày một giao diện nhắc người dùng cung cấp địa chỉ email của họ, rồi gọi sendSignInLinkToEmail() để yêu cầu Firebase gửi đường liên kết xác thực đến email của người dùng.

  1. Tạo đối tượng ActionCodeSettings để cung cấp cho Firebase hướng dẫn về cách tạo đường liên kết đến email. Đặt các trường sau:

    • url: Đường liên kết sâu để nhúng và mọi trạng thái khác cần truyền. Miền của đường liên kết phải nằm trong danh sách cho phép trong danh sách các miền được uỷ quyền của Bảng điều khiển của Firebase. Bạn có thể tìm thấy miền này bằng cách chuyển đến thẻ Phương thức đăng nhập (Xác thực -> Phương thức đăng nhập). Đường liên kết này sẽ chuyển hướng người dùng đến URL này nếu họ chưa cài đặt ứng dụng trên thiết bị và không thể cài đặt ứng dụng.

    • androidPackageNameIOSBundleId: Các ứng dụng sẽ sử dụng khi mở đường liên kết đăng nhập trên thiết bị Android hoặc iOS. Tìm hiểu thêm về cách định cấu hình Đường liên kết động của Firebase để mở đường liên kết hành động qua email thông qua ứng dụng di động.

    • handleCodeInApp: Đặt thành true. Không giống như các thao tác email ngoài nhóm khác (đặt lại mật khẩu và xác minh email), bạn phải luôn hoàn tất thao tác đăng nhập trong ứng dụng. Lý do là khi kết thúc luồng, người dùng được dự kiến sẽ đăng nhập và trạng thái Xác thực của họ vẫn được duy trì trong ứng dụng.

    • dynamicLinkDomain: Khi bạn đã xác định nhiều miền đường liên kết động tuỳ chỉnh cho một dự án, hãy chỉ định miền nào cần sử dụng khi đường liên kết sẽ được mở thông qua một ứng dụng di động cụ thể (ví dụ: example.page.link). Nếu không, miền đầu tiên sẽ tự động được chọn.

    var acs = ActionCodeSettings(
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true
        handleCodeInApp: true,
        iOSBundleId: 'com.example.ios',
        androidPackageName: 'com.example.android',
        // installIfNotAvailable
        androidInstallApp: true,
        // minimumVersion
        androidMinimumVersion: '12');
    
  2. Yêu cầu người dùng cung cấp email của họ.

  3. Gửi đường liên kết xác thực đến email của người dùng và lưu email của người dùng phòng trường hợp người dùng hoàn tất quá trình đăng nhập vào email trên cùng một thiết bị.

    var emailAuth = 'someemail@domain.com';
    FirebaseAuth.instance.sendSignInLinkToEmail(
            email: emailAuth, actionCodeSettings: acs)
        .catchError((onError) => print('Error sending email verification $onError'))
        .then((value) => print('Successfully sent email verification'));
    });
    

Các mối lo ngại về bảo mật

Để ngăn hành vi sử dụng đường liên kết đăng nhập để đăng nhập với tư cách người dùng ngoài ý muốn hoặc bật một thiết bị ngoài ý muốn, tính năng Xác thực Firebase yêu cầu địa chỉ email của người dùng phải khi hoàn tất quy trình đăng nhập. Để đăng nhập thành công, email này phải khớp với địa chỉ được dùng để gửi đường liên kết đăng nhập ban đầu.

Bạn có thể đơn giản hoá quy trình này cho những người dùng mở đường liên kết đăng nhập trên cùng một trang thiết bị họ yêu cầu liên kết, bằng cách lưu trữ địa chỉ email của họ trên máy tính - cho bằng SharedPreferences – khi bạn gửi email đăng nhập. Sau đó: sử dụng địa chỉ này để hoàn tất quy trình. Không chuyển email của người dùng vào các tham số URL chuyển hướng và sử dụng lại dưới dạng thao tác này có thể cho phép chèn phiên.

Sau khi hoàn tất đăng nhập, mọi cơ chế đăng nhập chưa được xác minh trước đó sẽ bị xoá khỏi người dùng và mọi phiên hoạt động hiện có đều sẽ mất hiệu lực. Ví dụ: nếu trước đây ai đó đã tạo một tài khoản chưa được xác minh cho email và mật khẩu, thì mật khẩu của người dùng sẽ bị xoá để ngăn kẻ mạo danh đã xác nhận quyền sở hữu và tạo tài khoản chưa được xác minh đó từ đăng nhập lại bằng email và mật khẩu chưa được xác minh.

Ngoài ra, hãy nhớ sử dụng URL HTTPS trong phiên bản chính thức để tránh việc đường liên kết bị có thể bị chặn bởi các máy chủ trung gian.

Tính năng Xác thực Firebase sử dụng Đường liên kết động của Firebase để gửi đường liên kết email đến thiết bị di động. Để hoàn tất quy trình đăng nhập qua ứng dụng dành cho thiết bị di động, bạn phải định cấu hình ứng dụng để phát hiện đường liên kết đến ứng dụng, phân tích cú pháp đường liên kết sâu cơ bản, sau đó hoàn tất quá trình đăng nhập.

  1. Thiết lập ứng dụng của bạn để nhận Đường liên kết động trên Flutter trong hướng dẫn này.

  2. Trong trình xử lý đường liên kết, hãy kiểm tra xem đường liên kết có được dùng để xác thực đường liên kết email hay không. Nếu có, hãy hoàn tất quy trình đăng nhập.

    // Confirm the link is a sign-in with email link.
    if (FirebaseAuth.instance.isSignInWithEmailLink(emailLink)) {
      try {
        // The client SDK will parse the code from the link for you.
        final userCredential = await FirebaseAuth.instance
            .signInWithEmailLink(email: emailAuth, emailLink: emailLink);
    
        // You can access the new user via userCredential.user.
        final emailAddress = userCredential.user?.email;
    
        print('Successfully signed in with email link!');
      } catch (error) {
        print('Error signing in with email link.');
      }
    }
    

Bạn cũng có thể liên kết phương pháp xác thực này với một người dùng hiện có. Ví dụ: người dùng đã xác thực trước đó bằng một nhà cung cấp khác, chẳng hạn như số điện thoại, có thể thêm phương thức đăng nhập này vào tài khoản hiện có của mình.

Sự chênh lệch sẽ nằm trong nửa sau của thao tác:

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.linkWithCredential(authCredential);
} catch (error) {
    print("Error linking emailLink credential.");
}

Có thể sử dụng công cụ này để xác thực lại người dùng liên kết email trước khi chạy hoạt động nhạy cảm.

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.reauthenticateWithCredential(authCredential);
} catch (error) {
    print("Error reauthenticating credential.");
}

Tuy nhiên, do luồng có thể kết thúc trên một thiết bị khác nơi người dùng ban đầu chưa đăng nhập, thì quy trình này có thể chưa hoàn tất. Trong trường hợp đó, lỗi có thể hiển thị với người dùng để buộc họ mở đường liên kết trên cùng một thiết bị. Hơi nhiều có thể được chuyển trong liên kết để cung cấp thông tin về loại thao tác và uid của người dùng.

Nếu bạn tạo dự án vào hoặc sau ngày 15 tháng 9 năm 2023, hãy liệt kê email tính năng bảo vệ được bật theo mặc định. Tính năng này cải thiện độ bảo mật của tài khoản người dùng của dự án, nhưng chế độ này sẽ vô hiệu hoá fetchSignInMethodsForEmail() mà trước đây chúng tôi khuyên dùng để triển khai quy trình ưu tiên giá trị nhận dạng.

Mặc dù bạn có thể tắt tính năng bảo vệ liệt kê email cho dự án của mình, nhưng chúng tôi không nên làm như vậy.

Xem tài liệu về biện pháp bảo vệ liệt kê email để biết thêm chi tiết.

Các bước tiếp theo

Sau khi người dùng tạo một tài khoản mới, tài khoản này sẽ được lưu trữ như một phần của dự án Firebase và có thể được dùng để xác định người dùng trên mọi ứng dụng trong dự án, bất kể người dùng đã sử dụng phương thức đăng nhập nào.

Trong ứng dụng của mình, bạn có thể lấy thông tin hồ sơ cơ bản của người dùng từ Đối tượng User. Xem phần Quản lý người dùng.

Trong Cơ sở dữ liệu theo thời gian thực của Firebase và Quy tắc bảo mật của Cloud Storage, bạn có thể lấy mã nhận dạng người dùng duy nhất của người dùng đã đăng nhập từ biến auth rồi sử dụng mã đó để kiểm soát loại dữ liệu mà người dùng có thể truy cập.

Bạn có thể cho phép người dùng đăng nhập vào ứng dụng của mình bằng nhiều phương thức xác thực nhà cung cấp bằng cách liên kết thông tin đăng nhập của nhà cung cấp dịch vụ xác thực) với tài khoản người dùng hiện có.

Để đăng xuất một người dùng, hãy gọi signOut():

await FirebaseAuth.instance.signOut();