Xác thực bằng Firebase bằng đường liên kết email trên các nền tảng của Apple

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 cho họ email có chứa đường liên kết mà người dùng có thể nhấp vào để đăng nhập. Trong quá trình này, địa chỉ email của người dùng 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 rủi ro sử dụng lại mật khẩu trên các ứng dụng, điều này có thể làm giảm tính bảo mật của ngay cả những mật khẩu được chọn kỹ lưỡng.
  • Khả năng xác thực người dùng đồng thời xác minh rằng người dùng là chủ sở hữu hợp pháp của đị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 bắt buộc phải sở hữu 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ật khẩu (có thể rườm rà trên thiết bị di động).
  • Người dùng hiện tại trước đây đã đă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ụ: người dùng quên mật khẩu vẫn có thể đăng nhập mà không cần đặt lại mật khẩu.

Trước khi bắt đầu

Sử dụng Trình quản lý gói Swift để cài đặt và quản lý các phần phụ thuộc Firebase.

  1. Trong Xcode, khi dự án ứng dụng của bạn đang mở, hãy chuyển đến File > Add Packages (Tệp > Thêm gói).
  2. Khi được nhắc, hãy thêm kho lưu trữ SDK nền tảng Apple của Firebase:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Chọn thư viện Xác thực Firebase.
  5. Thêm cờ -ObjC vào mục Cờ trình liên kết khác trong chế độ cài đặt bản dựng của mục tiêu.
  6. Khi hoàn tất, Xcode sẽ tự động bắt đầu phân giải và tải các phần phụ thuộc của bạn xuống ở chế độ nền.

Để đăng nhập người dùng bằng đường liên kết email, trước tiên bạn phải bật Nhà cung cấp email và Phương thức đăng nhập bằng đường liên kết 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 tính năng đăng nhập qua đường liên kết email.
  3. Cũng trong phần này, hãy bật phương thức đăng nhập Đường liên kết qua email (đăng nhập không cần mật khẩu).
  4. Nhấp vào Lưu.

Để bắt đầu quy trình xác thực, hãy hiển thị cho người dùng một giao diện nhắc người dùng cung cấp địa chỉ email của họ, sau đó gọi sendSignInLink để 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. Đối tượng này sẽ 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: Liên kết sâu để nhúng và mọi trạng thái bổ sung được 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 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).
    • iOSBundleID và androidPackageName : Các ứng dụng sẽ sử dụng khi đường liên kết đăng nhập mở trên thiết bị Android hoặc Apple. Tìm hiểu thêm về cách định cấu hình 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.
    • xử lýCodeInApp: Đặ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), hoạt động đăng nhập phải luôn được hoàn tất 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.
    • dynamicLinkMiền: Khi có nhiều miền đường liên kết động tuỳ chỉnh được xác định cho một dự án, hãy chỉ định miền 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ể (chẳng hạn như example.page.link). Nếu không, miền đầu tiên sẽ tự động được chọn.

    Swift

    let actionCodeSettings = ActionCodeSettings()
    actionCodeSettings.url = URL(string: "https://www.example.com")
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = true
    actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)
    actionCodeSettings.setAndroidPackageName("com.example.android",
                                             installIfNotAvailable: false, minimumVersion: "12")
    

    Objective-C

    FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init];
    [actionCodeSettings setURL:[NSURL URLWithString:@"https://www.example.com"]];
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = YES;
    [actionCodeSettings setIOSBundleID:[[NSBundle mainBundle] bundleIdentifier]];
    [actionCodeSettings setAndroidPackageName:@"com.example.android"
                        installIfNotAvailable:NO
                               minimumVersion:@"12"];
    

    Để tìm hiểu thêm về ActionCodeSettings, hãy tham khảo phần Chuyển trạng thái trong thao tác qua email.

  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 trong 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ị.

    Swift

    Auth.auth().sendSignInLink(toEmail: email,
                               actionCodeSettings: actionCodeSettings) { error in
      // ...
        if let error = error {
          self.showMessagePrompt(error.localizedDescription)
          return
        }
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        UserDefaults.standard.set(email, forKey: "Email")
        self.showMessagePrompt("Check your email for link")
        // ...
    }
    

    Objective-C

    [[FIRAuth auth] sendSignInLinkToEmail:email
                       actionCodeSettings:actionCodeSettings
                               completion:^(NSError *_Nullable error) {
      // ...
        if (error) {
          [self showMessagePrompt:error.localizedDescription];
           return;
        }
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        [NSUserDefaults.standardUserDefaults setObject:email forKey:@"Email"];
        [self showMessagePrompt:@"Check your email for link"];
        // ...
    }];
    

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

Để tránh việc 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 trên thiết bị không mong muốn, tính năng Xác thực Firebase yêu cầu cung cấp địa chỉ email của người dùng khi hoàn tất quy trình đăng nhập. Để đăng nhập thành công, địa chỉ email này phải khớp với địa chỉ 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 thiết bị mà họ yêu cầu đường liên kết, bằng cách lưu trữ địa chỉ email của họ trên máy khi bạn gửi email đăng nhập. Sau đó, sử dụng địa chỉ này để hoàn tất quy trình.

Sau khi hoàn tất quy trình đă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 hiện có 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 có cùng 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 đó đăng nhập lại bằng cùng một tài khoản.

Hoàn tất quy trình đăng nhập trong ứng dụng di động của Apple

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 qua 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ơ sở, sau đó hoàn tất quy trình đăng nhập.

Tính năng Xác thực Firebase sử dụng Đường liên kết động của Firebase khi gửi đường liên kết sẽ được mở trong ứng dụng dành cho thiết bị di động. Để sử dụng tính năng này, bạn cần định cấu hình Đường liên kết động trong Bảng điều khiển của Firebase.

  1. Bật liên kết động của Firebase:

    1. Trong bảng điều khiển của Firebase, hãy mở mục Đường liên kết động.
    2. Nếu bạn chưa chấp nhận các điều khoản về Đường liên kết động và tạo một miền Đường liên kết động, hãy thực hiện ngay.

      Nếu bạn đã tạo một miền Đường liên kết động, hãy ghi lại miền đó. Miền Liên kết động thường có dạng như ví dụ sau:

      example.page.link

      Bạn sẽ cần giá trị này khi định cấu hình ứng dụng Apple hoặc Android để chặn đường liên kết đến.

  2. Định cấu hình các ứng dụng của Apple:

    1. Nếu dự định xử lý các đường liên kết này từ ứng dụng của mình, thì bạn cần chỉ định mã gói trong phần cài đặt dự án trên Bảng điều khiển của Firebase. Ngoài ra, bạn cũng cần chỉ định Mã cửa hàng ứng dụng và Mã nhóm nhà phát triển của Apple.
    2. Bạn cũng cần định cấu hình miền của trình xử lý thao tác qua email dưới dạng một Miền được liên kết trong các chức năng của ứng dụng. Theo mặc định, trình xử lý thao tác qua email được lưu trữ trên một miền như ví dụ sau:
      APP_ID.firebaseapp.com
    3. Nếu dự định phân phối ứng dụng sang iOS phiên bản 8 trở xuống, bạn cần đặt mã nhận dạng gói dưới dạng lược đồ tuỳ chỉnh cho các URL nhận được.
    4. Để biết thêm thông tin về điều này, hãy tham khảo bài viết Hướng dẫn về cách nhận Đường liên kết động của nền tảng Apple.

Sau khi bạn nhận được đường liên kết như mô tả ở trên, hãy xác minh rằng đường liên kết đó dùng để xác thực đường liên kết email rồi hoàn tất quy trình đăng nhập.

Swift

if Auth.auth().isSignIn(withEmailLink: link) {
        Auth.auth().signIn(withEmail: email, link: self.link) { user, error in
          // ...
        }
}

Objective-C

if ([[FIRAuth auth] isSignInWithEmailLink:link]) {
    [[FIRAuth auth] signInWithEmail:email
                               link:link
                         completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      // ...
    }];
}

Để tìm hiểu cách xử lý quy trình đăng nhập bằng đường liên kết qua email trong ứng dụng Android, hãy tham khảo hướng dẫn dành cho Android.

Để tìm hiểu cách xử lý quy trình đăng nhập bằng đường liên kết email trong ứng dụng web, hãy tham khảo Hướng dẫn web.

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 đây 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 tại của họ.

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

Swift

  let credential = EmailAuthCredential.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.link(with: credential) { authData, error in
    if (error) {
      // And error occurred during linking.
      return
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }

Objective-C

  FIRAuthCredential *credential =
      [FIREmailAuthProvider credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      linkWithCredential:credential
              completion:^(FIRAuthDataResult *_Nullable result,
                           NSError *_Nullable error) {
    if (error) {
      // And error occurred during linking.
      return;
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }];

Tính năng này cũng có thể được dùng để xác thực lại người dùng đường liên kết email trước khi chạy một thao tác nhạy cảm.

Swift

  let credential = EmailAuthProvider.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.reauthenticate(with: credential) { authData, error in
    if (error) {
      // And error occurred during re-authentication.
      return
    }
    // The user was successfully re-authenticated.
  }

Objective-C

  FIRAuthCredential *credential =
      [FIREmailAuthCredential credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      reauthenticateWithCredential:credential
                        completion:^(FIRAuthDataResult *_Nullable result,
                                     NSError *_Nullable error) {
    if (error) {
      // And error occurred during re-authentication
      return;
    }
    // The user was successfully re-authenticated.
  }];

Tuy nhiên, vì luồng có thể kết thúc trên một thiết bị khác mà người dùng ban đầu chưa đăng nhập, nên luồng này có thể chưa hoàn tất. Trong trường hợp đó, người dùng có thể thấy lỗi để buộc họ mở đường liên kết trên cùng một thiết bị. Bạn có thể chuyển một số trạng thái trong đường 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, thì tính năng bảo vệ liệt kê email sẽ được bật theo mặc định. Tính năng này giúp cải thiện độ bảo mật cho tài khoản người dùng của dự án, nhưng vô hiệu hoá phương thức fetchSignInMethodsForEmail() mà trước đây chúng tôi đề xuất để triển khai quy trình ưu tiên giá trị nhận dạng.

Mặc dù có thể tắt tính năng bảo vệ liệt kê email cho dự án của mình, nhưng bạn 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 thông tin chi tiết.

Các bước tiếp theo

Sau khi người dùng đăng nhập lần đầu tiên, một tài khoản người dùng mới sẽ được tạo và liên kết với thông tin đăng nhập (chẳng hạn như tên người dùng và mật khẩu, số điện thoại hoặc thông tin của nhà cung cấp dịch vụ xác thực) mà người dùng đã đăng nhập. Tài khoản mới này được lưu trữ như một phần trong 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 của bạn, bất kể người dùng đăng nhập bằng cách nào.

  • Trong các ứng dụng, 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 Quy tắc bảo mật của Cloud Storage và Cơ sở dữ liệu theo thời gian thực của Firebase, bạn có thể lấy mã nhận dạng người dùng riêng biệt của người dùng đã đăng nhập từ biến auth rồi sử dụng mã này để kiểm soát những 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 thông qua nhiều nhà cung cấp dịch vụ xác thực 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 một 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:.

Swift

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}

Objective-C

NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

Bạn cũng nên thêm mã xử lý lỗi cho toàn bộ các lỗi xác thực. Hãy xem bài viết Xử lý lỗi.