Apple プラットフォームで GitHub を使用して認証する

Firebase SDK を使用して汎用の OAuth ログインをアプリに統合し、エンドツーエンドのログインフローを実行することで、ユーザーが Firebase での認証に GitHub などの OAuth プロバイダを使用できるようになります。

始める前に

GitHub アカウントを使用してユーザーをログインさせるには、まず Firebase プロジェクトのログイン プロバイダとして GitHub を有効にする必要があります。

Swift Package Manager を使用して Firebase の依存関係のインストールと管理を行います。

  1. Xcode でアプリのプロジェクトを開いたまま、[File] > [Add Packages] の順に移動します。
  2. プロンプトが表示されたら、Firebase Apple プラットフォーム SDK リポジトリを追加します。
  3.   https://github.com/firebase/firebase-ios-sdk
  4. Firebase Authentication ライブラリを選択します。
  5. 上記の作業が完了すると、Xcode は依存関係の解決とバックグラウンドでのダウンロードを自動的に開始します。

次に、構成ステップを行います。

  1. Firebase コンソールで [Authentication] セクションを開きます。
  2. [Sign-in method] タブで、[GitHub] プロバイダを有効にします。
  3. そのプロバイダのデベロッパー コンソールで取得したクライアント IDクライアント シークレットをプロバイダ構成に追加します。
    1. GitHub でデベロッパー アプリケーションとしてアプリを登録し、アプリの OAuth 2.0 クライアント IDクライアント シークレットを取得します。
    2. GitHub アプリの構成にあるアプリ設定ページで、Firebase OAuth リダイレクト URImy-app-12345.firebaseapp.com/__/auth/handler など)を認可コールバック URL として設定します。
  4. [保存] をクリックします。

Firebase SDK を使用したログインフローの処理

Firebase Apple プラットフォーム SDK でログインフローを処理する手順は次のとおりです。

  1. Xcode プロジェクトにカスタム URL スキームを追加します。

    1. プロジェクト構成を開きます(左側のツリービューでプロジェクト名をダブルクリックします)。[TARGETS] セクションでアプリを選択し、[Info] タブを開いて [URL Types] セクションを展開します。
    2. [+] ボタンをクリックし、エンコードされたアプリ ID を URL スキームとして追加します。エンコードされたアプリ ID は、Firebase コンソールの [全般設定] ページで、iOS アプリのセクションで確認できます。その他のフィールドは空白にしておきます。

      完了すると、構成は次のようになります(ただし、値はアプリケーションによって異なります)。

      Xcode のカスタム URL スキーム設定インターフェースのスクリーンショット

  2. プロバイダ ID github.com を使用して、OAuthProvider のインスタンスを作成します。

    Swift

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

    Objective-C

        FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"github.com"];
        
  3. 省略可: OAuth リクエストと一緒に送信したい追加のカスタム OAuth パラメータを指定します。

    Swift

        provider.customParameters = [
          "allow_signup": "false"
        ]
        

    Objective-C

        [provider setCustomParameters:@{@"allow_signup": @"false"}];
        

    GitHub がサポートするパラメータについては、GitHub の OAuth に関するドキュメントをご覧ください。setCustomParameters で Firebase の必須パラメータを渡すことはできません。該当するパラメータは、client_idredirect_uriresponse_typescopestate です。

  4. 省略可: 認証プロバイダにリクエストする、基本的なプロフィール以外の追加の OAuth 2.0 スコープを指定します。アプリケーションで GitHub API から限定公開のユーザーデータへのアクセスが必要な場合は、GitHub のデベロッパー コンソールの [API Permissions] で、GitHub API にアクセスする権限をリクエストする必要があります。リクエストされた OAuth スコープは、アプリの API 権限で事前構成されたものと完全に一致している必要があります。

    Swift

        // Request read access to a user's email addresses.
        // This must be preconfigured in the app's API permissions.
        provider.scopes = ["user:email"]
        

    Objective-C

        // Request read access to a user's email addresses.
        // This must be preconfigured in the app's API permissions.
        [provider setScopes:@[@"user:email"]];
        

    詳しくは、GitHub のスコープに関するドキュメントをご覧ください。

  5. 省略可: アプリがユーザーに reCAPTCHA を表示する際の SFSafariViewController または UIWebView の提示方法をカスタマイズするには、AuthUIDelegate プロトコルに従ったカスタムクラスを作成して、そのクラスを credentialWithUIDelegate に渡します。

  6. OAuth プロバイダ オブジェクトを使用して Firebase での認証を行います。

    Swift

        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.
    
              guard let oauthCredential = authResult.credential as? OAuthCredential else { return }
              // GitHub OAuth access token can also be retrieved by:
              // oauthCredential.accessToken
              // GitHub OAuth ID token can be retrieved by calling:
              // 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.
    
              FIROAuthCredential *oauthCredential = (FIROAuthCredential *)authResult.credential;
              // GitHub OAuth access token can also be retrieved by:
              // oauthCredential.accessToken
              // GitHub OAuth ID token can be retrieved by calling:
              // oauthCredential.idToken
            }];
          }
        }];
        

    OAuth アクセス トークンを使用して、GitHub API を呼び出せます。

    たとえば、基本的なプロフィール情報を取得するには、Authorization ヘッダーにアクセス トークンを渡して REST API を呼び出します。

    https://api.github.com/user
    
  7. 上記の例ではログインフローを中心に説明していますが、GitHub プロバイダを既存のユーザーにリンクすることもできます。たとえば、複数のプロバイダを同じユーザーにリンクして、どれでもログイン可能にすることができます。

    Swift

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

    Objective-C

        [[FIRAuth auth].currentUser
            linkWithCredential:credential
                    completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
          if (error) {
            // Handle error.
          }
          // GitHub credential is linked to the current user.
          // IdP data available in authResult.additionalUserInfo.profile.
          // GitHub OAuth access token is can also be retrieved by:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // GitHub OAuth ID token can be retrieved by calling:
          // ((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 is can also be retrieved by:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // GitHub OAuth ID token can be retrieved by calling:
          // (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 is can also be retrieved by:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // GitHub OAuth ID token can be retrieved by calling:
          // ((FIROAuthCredential *)authResult.credential).idToken
        }];
        

次のステップ

ユーザーが初めてログインすると、新しいユーザー アカウントが作成され、ユーザーがログイン時に使用した認証情報(ユーザー名とパスワード、電話番号、または認証プロバイダ情報)にアカウントがリンクされます。この新しいアカウントは Firebase プロジェクトの一部として保存され、ユーザーのログイン方法にかかわらず、プロジェクトのすべてのアプリでユーザーを識別するために使用できます。

  • アプリでは、User オブジェクトからユーザーの基本的なプロフィール情報を取得できます。ユーザーを管理するをご覧ください。

  • Firebase Realtime Database と Cloud Storage のセキュリティ ルールでは、ログイン済みユーザーの一意のユーザー ID を auth 変数から取得し、それを使用して、ユーザーがアクセスできるデータを管理できます。

既存のユーザー アカウントに認証プロバイダの認証情報をリンクすることで、ユーザーは複数の認証プロバイダを使用してアプリにログインできるようになります。

ユーザーのログアウトを行うには、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;
}

さまざまな認証エラーに対応できるようにエラー処理コードを追加することもできます。エラーの処理をご覧ください。