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 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

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 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 xuống các phần phụ thuộc trong nề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 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. Ghi chú 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 tính năng Đăng nhập bằng đườ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 trình bày 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 cung cấp cho Firebase hướng dẫn về cách tạo liên kết 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 liên kết phải nằm trong danh sách cho phép trong danh sách Bảng điều khiển của Firebase các miền được uỷ quyền. Bạn có thể tìm thấy những 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 liên kết đăng nhập được 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 dành cho thiết bị di động.
    • xử lýCodeInApp: Đặt thành true. Hoạt động đăng nhập phải luôn hoàn tất trong ứng dụng không giống như các hành động email khác ngoài nhóm (mật khẩu đặt lại và xác minh email). Điều này là do, ở cuối luồng, người dùng cần đăng nhập và trạng thái Xác thực của họ vẫn tồn tại trong ứng dụng.
    • dynamicLinkMiền: Khi có nhiều miền đường liên kết động tuỳ chỉnh đối với một dự án, chỉ định sử dụng dự án nào khi liên kết được mở qua một ứng dụng di động được chỉ định (ví dụ: example.page.link). Nếu không, miền đầu tiên được chọn tự động.

    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 Trạng thái chuyển 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 đó khi người dùng hoàn tất quá trình đăng nhập 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

Để 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 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 đă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 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 Liên kết động của Firebase để gửi đường liên kết email đến thiết bị di động của bạn. Để hoàn tất quá trình đăng nhập qua ứng dụng dành cho thiết bị di động, ứng dụng phải được định cấu hình để phát hiện liên kết ứng dụng sắp tới, hãy phân tích cú pháp đường liên kết sâu cơ bản rồi hoàn tất quá trình đăng nhập.

Tính năng Xác thực Firebase sử dụng Liên kết động Firebase khi gửi một được mở trong ứng dụng dành cho thiết bị di động. Để sử dụng . Bạn cần định cấu hình 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. Trường hợp bạn chưa chấp nhận các điều khoản về Đường liên kết động và đã tạo Đường liên kết động , hãy thực hiện ngay bây giờ.

      Nếu bạn đã tạo một miền Đường liên kết động, hãy ghi lại miền đó. Đường 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 bạn dự định xử lý các liên kết này từ đơn đăng ký của mình, Cần chỉ định mã gói trong Bảng điều khiển của Firebase phần cài đặt dự án. Ngoài ra, Mã App Store và Nhà phát triển của Apple Bạn cũng cần chỉ định mã nhóm.
    2. Bạn cũng cần phải định cấu hình miền của trình xử lý hành động qua email dưới dạng 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ý tác vụ email được lưu trữ trên một miền như ví dụ sau:
      APP_ID.firebaseapp.com
    3. Nếu bạn dự định phân phối ứng dụng của mình cho iOS phiên bản 8 trở xuống, bạn sẽ cần đặt mã nhận dạng gói làm lược đồ tuỳ chỉnh cho URL.
    4. Để biết thêm thông tin về vấn đề này, hãy tham khảo Nhận hướng dẫn về Đườ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ư được mô tả ở trên, hãy xác minh rằng đường liên kết đó dành cho email liên kết xác thực và hoàn tất đă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 email trên thiết bị 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 trên web ứng dụng, 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 đó 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:

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.
  }];

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.

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 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 trạng thái 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 đă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à được liên kết với thông tin đăng nhập—tức là tên người dùng và mật khẩu, số điện thoại số hoặc thông tin của nhà cung cấp dịch vụ xác thực – người dùng đã đăng nhập. Thông tin mới này được lưu trữ như một phần của dự án Firebase và có thể được dùng để xác định một 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 ứ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ừ 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à Cloud Storage Quy tắc bảo mật, 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, để 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 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:.

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ộ phạm vi xác thực . Hãy xem bài viết Xử lý lỗi.