Posted at

【Firebase】メールリンク認証の実装【iOS】


はじめに

本記事では、iOSアプリにおけるFirebaseAuthを用いたメールリンク認証の実装方法を解説します。


メールリンク認証とは

メールリンク認証とは、メールをユーザに送信し、そこに記載されたログイン用のリンクからログインさせる認証方法です。このメールリンク認証には次のようなメリットがあります。


  • 登録やログインが簡単

  • パスワードが必要ない

  • メールアドレスの認証も同時に行える

ユーザも簡単にログインでき、デベロッパもパスワード系の機能(バリデーションや再設定など)を実装しなくて良いので、win-winな認証方法であると言えます。


準備

iOSおよびFirebaseコンソールでのセットアップについては省きます。まだの方は公式チュートリアルなどを参考に設定してください。


各種IDの取得

Dynamic Linksを利用するには、iOSアプリの「App Store ID」と「チームID」が必要になります。どちらもリリース作業時に目にするようなIDですが、リリース準備前でも取得できます。


チームIDの取得

Apple Developerから「Certificates, Identifiers & Profiles」セクションを開き、アプリに紐付けたApp IDを確認します。未作成の場合は新規作成してください。Certificatesの設定などがありますが、本記事では説明を省きます。作成したApp IDのBundle IDとXcode ProjectでのBundle IDを一致させる必要があることに注意してください。

App IDの「Prefix」がチームIDになります。


App Store IDの取得

App Store Connectの「マイApp」から該当アプリを選択します。未作成の場合は手順に従い新規Appを作ってください。「App情報」の「一般情報」にある「Apple ID」がApp Store IDになります。


Firebaseコンソールのアプリ設定の更新

Firebaseコンソールの「プロジェクトの設定」内の中に先ほど取得したApp Store IDとチームIDを入力するところがあるのでここを埋めます。この2つの値が設定されていないと、Dynamic Linkで開くアプリとして選択できません。


実装

メールリンク認証は以下の手順で実装することができます。


  1. メールリンク認証の有効化

  2. Firebase Dynamic Linksの作成

  3. Xcode Projectの設定


メールリンク認証の有効化

Firebaseコンソールの「Authentication」セクションを開きます。

上部タブの「ログイン方法」から、「メール/パスワード」と「メールリンク」を有効にし、保存します。


Firebase Dynamic Linksの作成

コンソールの「Dynamic Links」セクションを開きます。Dynamic Linksの利用規約に同意していない場合は同意してください。

Dynamic Linksに使用するドメインを作成します。すでに作成済みの場合はスキップしてください。ここで作成するドメインは、Xcode上のプロジェクト設定で入力するものになります。サブドメインはアプリ名などにすると良いと思います。

ドメインが作成できたら、「新しいダイナミックリンク」をクリックし、表示される手順に沿って作成します。「短縮URLのリンク設定」は、特にこだわりがなければデフォルト値でよいです。

「ダイナミックリンクの設定」では、ディープリンクURLと、今作成しているダイナミックリンクの名前を設定します。

ディープリンクURLは実際に存在するURLでなくても良いので、アプリや処理がわかりやすいものにしておきましょう(e.g. https://sampleapp.com/signin)。このURLはアプリ側で、どのような処理を期待するリンクからアプリが開かれたのかを判別するのに用いられます。本記事ではログインを紹介していますが、このURLで振り分けることで、クーポン付与や特定ページの表示などにも利用できます。

ダイナミックリンク名はFirebaseコンソールのみに表示される名前になります。

「iOS用のリンク動作の定義」では、「ディープリンクをiOSアプリで開く」を選択し、プルダウンから開くアプリを選択します。他の設定はお好みで構いません。

その後に続くAndroidの設定などはどのような値でも大丈夫です。「作成」を押したらダイナミックリンクが追加されます。


ドメインの承認

先ほどのダイナミックリンクで指定したディープリンクURLのドメインは事前に承認しておく必要があります。メールログインを有効にした「Authentication」セクション内の「ログイン方法」タブの下の方に「承認済みドメイン」という項目があるので、こちらにディープリンクURLのドメインを追加します。(e.g. https://sampleapp.com/signinの場合はsampleapp.com

以上でFirebaseコンソール側の作業は完了です。


Xcode Projectの設定

アプリのTargetsの「Capabilities」にて、「Associated Domains」をONにします。「Domains」にapplinks:サブドメイン名.page.linkを追加してください。applinks:の後には、Firebaseコンソールの「Dynamic Links」セクションで作成したドメインが入ります。(e.g. sampleapp.page.link


ユーザのメールアドレスに認証リンクを送信

ここまで完了したら、あとはコーディングだけです。


ActionCodeSettingsオブジェクトの作成

ActionCodeSettingsは、メールリンクの作成方法をFirebaseに伝えるものです。ディープリンクURLには、Firebaseコンソール上で作成したダイナミックリンクのディープリンクURLを指定します。(e.g. https://sampleapp.com/signin

import FirebaseAuth

// ...
let actionCodeSettings = ActionCodeSettings()
actionCodeSettings.url = URL(string: "ディープリンクURL")
actionCodeSettings.handleCodeInApp = true
actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)


メールアドレスに認証リンクを送信

sendSignInLinkメソッドにメールアドレスとactionCodeSettingsを渡します。actionCodeSettingsに指定したディープリンクURLがFirebaseコンソール上で未承認だと、リンクの送信に失敗してしまいます。成功時には「メールのリンクを確認してください」などのアラートを出すと親切ですね。

Auth.auth().sendSignInLink(toEmail:email,

actionCodeSettings: actionCodeSettings) { error in
if let error = error {
// リンクの送信失敗
return
}
// リンクの送信成功
}


リンクを確認してログインする

メールに記載されたリンクをタップするとこのようなページに飛びます。OPENをタップするとアプリが開かれます。

このボタンからアプリを開くと、AppDelegate内のapplication(_:continue:restorationHandler:)メソッドが呼ばれます。ログインには受信したディープリンクURLと入力されたメールアドレスの2つが必要になるので、UserDefaultsなどを利用してよしなに情報を保持・取得しましょう。公式ドキュメントではUserDefaultsに保存し、別画面でボタンを押した際にログイン処理を走らせています。signInメソッドが成功すればメールリンク認証は完了です。


AppDelegate.swift

import FirebaseAuth

import FirebaseDynamicLinks
// ...
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard let url = userActivity.webpageURL else { return true }
let handled = DynamicLinks.dynamicLinks().handleUniversalLink(url) { [weak self] (link, _) in
guard let linkURL = link?.url else { return }
self?.handlePasswordlessSignIn(withURL: linkURL)
}
return handled
}

func handlePasswordlessSignIn(withURL url: URL) {
let link = url.absoluteString
if Auth.auth().isSignIn(withEmailLink: link) {
Auth.auth().signIn(withEmail: "メールアドレス", link: link) { [weak self] (result, error) in
if let error = error {
// ログイン失敗
return
}
// ログイン成功
}
}
}



まとめ

Firebaseのメールリンク認証をiOSアプリに実装する方法を解説しました。App Store IDやドメインの取得などは煩雑ですが、パスワードレスなログインによりユーザ体験は非常に向上するので、ぜひ導入してみてください :wink:


参考文献

iOSでメールリンクを使用してFirebase認証を行う