在 Apple 平台上使用 Microsoft 进行身份验证

要让您的用户能够使用 OAuth 提供方(如 Microsoft Azure Active Directory)进行 Firebase 身份验证,您可以使用 Firebase SDK 执行端到端登录流程,将基于网页的通用 OAuth 登录机制集成到您的应用中。

准备工作

如需让用户能够通过 Microsoft 账号(Azure Active Directory 和个人 Microsoft 账号)登录,您必须先启用 Microsoft 作为您的 Firebase 项目的登录服务提供方:

  1. 将 Firebase 添加到您的 Apple 项目
  2. Firebase 控制台中,打开 Auth 部分。
  3. Sign in method(登录方法)标签页中,启用 Microsoft 提供方。
  4. 将该提供方的开发者控制台中的客户端 ID客户端密钥添加至提供方配置:
    1. 如需注册 Microsoft OAuth 客户端,请按照快速入门:使用 Azure Active Directory v2.0 端点注册应用中的说明进行操作。 请注意,此端点同时支持使用 Microsoft 个人账号和 Azure Active Directory 账号进行登录。 详细了解 Azure Active Directory v2.0。
    2. 向这些提供方注册应用时,请务必将项目的 *.firebaseapp.com 网域注册为应用的重定向网域。
  5. 点击保存

使用 Firebase SDK 处理登录流程

如需使用 Firebase Apple 平台 SDK 处理登录流程,请按以下步骤操作:

  1. 将自定义网址方案 (URL scheme) 添加至 Xcode 项目中:

    1. 打开项目配置:在左侧的树状视图中双击项目名称。在目标部分中选择您的应用,然后选择信息标签页,并展开网址类型部分。
    2. 点击 + 按钮,然后将经过编码的应用 ID 添加为网址方案。您可以打开 Firebase 控制台的常规设置页面,在您的 iOS 应用部分找到经过编码的应用 ID。请将其他字段留空。

      完成上述操作后,您的配置应显示如下(但其中的值应替换为您的应用的值):

      Xcode 自定义网址方案设置界面的屏幕截图
  2. 使用提供方 ID microsoft.com 创建一个 OAuthProvider 实例。

    Swift

        var provider = OAuthProvider(providerID: "microsoft.com")
        

    Objective-C

        FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"microsoft.com"];
        
  3. 可选:指定您希望通过 OAuth 请求发送的其他自定义 OAuth 参数。

    Swift

        provider.customParameters = [
          "prompt": "consent",
          "login_hint": "user@firstadd.onmicrosoft.com"
        ]
        

    Objective-C

        [provider setCustomParameters:@{@"prompt": @"consent", @"login_hint": @"user@firstadd.onmicrosoft.com"}];
        

    如需查看 Microsoft 支持的参数,请参阅 Microsoft OAuth 文档。 请注意,您不能使用 setCustomParameters 传递 Firebase 必需的参数。这些参数包括 client_idresponse_typeredirect_uristatescoperesponse_mode

    如需仅允许来自特定 Azure AD 租户的用户登录应用,可以使用 Azure AD 租户的易记域名或该租户的 GUID 标识符。为此,您可以在自定义参数对象中指定“租户”字段。

    Swift

        provider.customParameters = [
          // Optional "tenant" parameter in case you are using an Azure AD
          // tenant. eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or
          // 'contoso.onmicrosoft.com' or "common" for tenant-independent
          // tokens. The default value is "common".
          "tenant": "TENANT_ID"
        ]
        

    Objective-C

        // Optional "tenant" parameter in case you are using an Azure AD tenant.
        // eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or
        // 'contoso.onmicrosoft.com' or "common" for tenant-independent tokens.
        // The default value is "common".
        provider.customParameters = @{@"tenant": @"TENANT_ID"};
        
  4. 可选:指定您希望向身份验证提供方申请获取的个人资料基本信息以外的额外 OAuth 2.0 范围。

    Swift

        provider.scopes = ["mail.read", "calendars.read"]
        

    Objective-C

        [provider setScopes:@[@"mail.read", @"calendars.read"]];
        

    如需了解详情,请参阅 Microsoft 权限和许可文档

  5. 可选:如果您希望自定义应用在向用户显示 reCAPTCHA 时如何呈现 SFSafariViewControllerUIWebView,请创建一个符合 AuthUIDelegate 协议的自定义类,并将其传递给 credentialWithUIDelegate

  6. 使用 OAuth 提供方对象进行 Firebase 身份验证。

    Swift

        // Replace nil with the custom class that conforms to AuthUIDelegate
        // you created in last step to use a customized web view.
        provider.getCredentialWith(nil) { credential, error in
          if error != nil {
            // Handle error.
          }
          if credential != nil {
            Auth().signIn(with: credential) { authResult, error in
              if error != nil {
                // Handle error.
              }
              // User is signed in.
              // IdP data available in authResult.additionalUserInfo.profile.
              // OAuth access token can also be retrieved:
              // (authResult.credential as? OAuthCredential)?.accessToken
              // OAuth ID token can also be retrieved:
              // (authResult.credential as? OAuthCredential)?.idToken
            }
          }
        }
        

    Objective-C

        [provider getCredentialWithUIDelegate:nil
                                   completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
          if (error) {
           // Handle error.
          }
          if (credential) {
            [[FIRAuth auth] signInWithCredential:credential
                                      completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
              if (error) {
                // Handle error.
              }
              // User is signed in.
              // IdP data available in authResult.additionalUserInfo.profile.
              // OAuth access token can also be retrieved:
              // ((FIROAuthCredential *)authResult.credential).accessToken
              // OAuth ID token can also be retrieved:
              // ((FIROAuthCredential *)authResult.credential).idToken
            }];
          }
        }];
        

    使用 OAuth 访问令牌,您可以调用 Microsoft Graph API

    例如,如需获取基本个人资料信息,您可以调用 REST API 并在 Authorization 标头中传递访问令牌:

    https://graph.microsoft.com/v1.0/me

    与 Firebase Authentication 支持的其他提供方不同,Microsoft 不提供照片网址,您必须通过 Microsoft Graph API 来请求个人资料照片的二进制数据。

    除了 OAuth 访问令牌,您还可以从 OAuthCredential 对象检索用户的 OAuth ID 令牌。ID 令牌中的 sub 声明取决于具体应用,该声明与 Firebase Auth 所使用的可通过 user.providerData[0].uid 访问的联合用户标识符不匹配。应改用 oid 声明字段。 使用 Azure AD 租户登录时,oid 声明将完全匹配。 不过,对于非租户,系统将用无效信息填充 oid 字段。对于联合 ID 4b2eabcdefghijkloid 的格式为 00000000-0000-0000-4b2e-abcdefghijkl

  7. 以上示例侧重的是登录流程。除此之外,您也可以使用 linkWithCredential 将 Microsoft 提供方与现有用户相关联。例如,您可以将多个提供方关联至同一个用户,以便使用任意一个进行登录。

    Swift

        Auth().currentUser.link(withCredential: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // Microsoft credential is linked to the current user.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // OAuth ID token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.idToken
        }
        

    Objective-C

        [[FIRAuth auth].currentUser
            linkWithCredential:credential
                    completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
          if (error) {
            // Handle error.
          }
          // Microsoft credential is linked to the current user.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // OAuth ID token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).idToken
        }];
        
  8. 上述模式同样适用于 reauthenticateWithCredential。对于要求用户必须在近期内登录过才能执行的敏感操作,可使用它来检索新的凭据。

    Swift

        Auth().currentUser.reauthenticateWithCredential(withCredential: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // User is re-authenticated with fresh tokens minted and
          // should be able to perform sensitive operations like account
          // deletion and email or password update.
          // IdP data available in result.additionalUserInfo.profile.
          // Additional OAuth access token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // OAuth ID token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.idToken
        }
        

    Objective-C

        [[FIRAuth auth].currentUser
            reauthenticateWithCredential:credential
                              completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
          if (error) {
            // Handle error.
          }
          // User is re-authenticated with fresh tokens minted and
          // should be able to perform sensitive operations like account
          // deletion and email or password update.
          // IdP data available in result.additionalUserInfo.profile.
          // Additional OAuth access token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // OAuth ID token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).idToken
        }];
        

在用户首次登录后,系统会创建一个新的用户账号,并将其与该用户登录时使用的凭据(即用户名和密码、电话号码或者身份验证提供方信息)相关联。此新账号存储在您的 Firebase 项目中,无论用户采用何种方式登录,您项目中的每个应用都可以使用此账号来识别用户。

  • 在您的应用中,您可以从 User 对象获取用户的基本个人资料信息。请参阅管理用户

  • 在您的 Firebase Realtime DatabaseCloud Storage 安全规则中,您可以从 auth 变量获取已登录用户的唯一用户 ID,然后利用此 ID 来控制用户可以访问哪些数据。

您可以通过将身份验证提供方凭据关联至现有用户账号,让用户可以使用多个身份验证提供方登录您的应用。

如需将用户退出登录,请调用 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;
}

您可能还需要为所有身份验证错误添加错误处理代码。请参阅处理错误