Google 致力于为黑人社区推动种族平等。查看具体举措

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

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

如果您已通过 Identity Platform 升级到 Firebase 身份验证,则可以使用您选择的符合 OpenID Connect (OIDC) 标准的提供商通过 Firebase 对您的用户进行身份验证。这使得使用 Firebase 本身不支持的身份提供程序成为可能。

在你开始之前

要使用 OIDC 提供商登录用户,您必须首先从提供商那里收集一些信息:

  • 客户端 ID :标识您的应用程序的提供商唯一的字符串。您的提供商可能会为您支持的每个平台分配不同的客户端 ID。这是您的提供商发布的 ID 令牌中的aud声明的值之一。

  • 客户端密码:提供者用来确认客户端 ID 所有权的密码字符串。对于每个客户端 ID,您都需要一个匹配的客户端密码。 (仅当您使用auth code flow时才需要此值,强烈建议您这样做。)

  • Issuer :标识您的提供者的字符串。此值必须是一个 URL,当附加/.well-known/openid-configuration时,它是提供者的 OIDC 发现文档的位置。例如,如果颁发者是https://auth.example.com ,则发现文档必须在https://auth.example.com/.well-known/openid-configuration可用。

获得上述信息后,启用 OpenID Connect 作为 Firebase 项目的登录提供程序:

  1. 将 Firebase 添加到您的 iOS 项目中。

  2. 如果您尚未使用 Identity Platform 升级到 Firebase 身份验证,请执行此操作。 OpenID Connect 身份验证仅在升级项目中可用。

  3. 在 Firebase 控制台的登录提供程序页面上,单击添加新提供程序,然后单击OpenID Connect

  4. 选择您将使用授权代码流还是隐式授权流

    如果您的提供者支持,您应该始终使用代码流。隐式流程不太安全,强烈建议不要使用它。

  5. 给这个提供者一个名字。请注意生成的提供程序 ID:类似于oidc.example-provider 。当您将登录代码添加到您的应用程序时,您将需要此 ID。

  6. 指定您的客户端 ID 和客户端密码,以及您的提供商的颁发者字符串。这些值必须与您的提供商分配给您的值完全匹配。

  7. 保存您的更改。

使用 Firebase SDK 处理登录流程

使用 OIDC 提供商通过 Firebase 对用户进行身份验证的最简单方法是使用 Firebase SDK 处理整个登录流程。

要使用 Firebase Apple 平台 SDK 处理登录流程,请执行以下步骤:

  1. 将自定义 URL 方案添加到您的 Xcode 项目:

    1. 打开您的项目配置:双击左侧树视图中的项目名称。从TARGETS部分中选择您的应用程序,然后选择Info选项卡,然后展开URL Types部分。
    2. 单击+按钮,并为您的反向客户端 ID 添加 URL 方案。要查找此值,请打开GoogleService-Info.plist配置文件,然后查找REVERSED_CLIENT_ID键。复制该键的值,并将其粘贴到配置页面上的URL 方案框中。将其他字段留空。

      完成后,您的配置应类似于以下内容(但使用特定于应用程序的值):

  2. 使用您在 Firebase 控制台中获得的提供程序 ID 创建OAuthProvider的实例。

    迅速

    var provider = OAuthProvider(providerID: "oidc.example-provider")
    

    Objective-C

    FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"oidc.example-provider"];
    
  3. 可选:指定要随 OAuth 请求一起发送的其他自定义 OAuth 参数。

    迅速

    provider.customParameters = [
      "login_hint": "user@example.com"
    ]
    

    Objective-C

    [provider setCustomParameters:@{@"login_hint": @"user@example.com"}];
    

    请与您的供应商核实其支持的参数。请注意,您不能使用setCustomParameters传递 Firebase 所需的参数。这些参数是client_idresponse_typeredirect_uristatescoperesponse_mode

  4. 可选:指定您希望从身份验证提供程序请求的基本配置文件之外的其他 OAuth 2.0 范围。

    迅速

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

    Objective-C

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

    请咨询您的提供商以了解其支持的范围。

  5. 可选:如果您想自定义应用在向用户显示 reCAPTCHA 时呈现SFSafariViewControllerUIWebView的方式,请创建一个符合FIRAuthUIDelegate协议的自定义类。

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

    迅速

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    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

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    [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
        }];
      }
    }];
    
  7. 虽然上述示例侧重于登录流程,但您还可以使用linkWithCredential将 OIDC 提供程序链接到现有用户。例如,您可以将多个提供商链接到同一个用户,允许他们使用其中任何一个登录。

    迅速

    Auth().currentUser.link(withCredential: credential) { authResult, error in
      if error != nil {
        // Handle error.
      }
      // OIDC 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.
      }
      // OIDC 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一起使用,它可用于检索需要最近登录的敏感操作的新凭据。

    迅速

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

手动处理登录流程

如果您已经在应用中实现了 OpenID Connect 登录流程,则可以直接使用 ID 令牌向 Firebase 进行身份验证:

迅速

let credential = OAuthProvider.credential(
    withProviderID: "oidc.example-provider",  // As registered in Firebase console.
    idToken: idToken,  // ID token from OpenID Connect flow.
    rawNonce: nil
)
Auth.auth().signIn(with: credential) { authResult, error in
    if error {
        // Handle error.
        return
    }
    // User is signed in.
    // IdP data available in authResult?.additionalUserInfo?.profile
}

Objective-C

FIROAuthCredential *credential =
    [FIROAuthProvider credentialWithProviderID:@"oidc.example-provider"  // As registered in Firebase console.
                                       IDToken:idToken  // ID token from OpenID Connect flow.
                                      rawNonce:nil];
[[FIRAuth auth] signInWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult,
                                      NSError * _Nullable error) {
    if (error != nil) {
        // Handle error.
        return;
    }
    // User is signed in.
    // IdP data available in authResult.additionalUserInfo.profile
}];

下一步

用户首次登录后,会创建一个新用户帐户并将其链接到凭据(即用户名和密码、电话号码或身份验证提供商信息),即用户登录时使用的凭据。这个新帐户作为 Firebase 项目的一部分存储,可用于在项目中的每个应用中识别用户,无论用户如何登录。

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

  • 在您的 Firebase 实时数据库和云存储安全规则中,您可以从auth变量中获取登录用户的唯一用户 ID,并使用它来控制用户可以访问哪些数据。

您可以通过将身份验证提供程序凭据链接到现有用户帐户来允许用户使用多个身份验证提供程序登录您的应用程序。

要注销用户,请调用signOut:

迅速

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

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