AndroidアプリでFirebaseを使ったメールリンク認証を作る際、
躓いたのでまとめておきます。
躓いたのでまとめておきます。
メールリンク認証とは
メールアドレスのみで認証する、パスワード設定が不要な認証方法です。
手順は
メールを受け取れるということは本人である証明。というセキュリティの考え方。
- アプリのユーザ登録画面からメールアドレスを入力してもらう
- Firebaseからそのメールアドレスに招待メールが送られる
- メールの招待RULをクリックすると、アプリが起動し認証完了(ユーザ登録完了)
Firebase側の実装
プロジェクトを作る
Firebaseのコンソールを開いて、「プロジェクトを追加」を押下
プロジェクト名は「MailLoginSample」※なんでもいい
Google アナリティクスはどちらでもいいと思うけど有効にした
Google アナリティクスの構成もデフォルトを選択
プロジェクト名は「MailLoginSample」※なんでもいい
Google アナリティクスはどちらでもいいと思うけど有効にした
Google アナリティクスの構成もデフォルトを選択
アプリを追加する
AndroidアプリとFirebaseを接続する為に「アプリを追加」する
作成したプロジェクトに入ると、「アプリを追加する」があるので追加していく
プラットフォーム選択は「Android」にする
プラットフォーム選択は「Android」にする
AndroidSdudioで新しくプロジェクトと作るときに設定するパッケージ名
公式での解説だとこの辺り
すでに作ってるアプリに機能実装したいけど、
パッケージ名何にしたかわからないときはGradleのapplicationIdを見る
アプリのニックネーム、証明書は未入力でよい
次に、設定ファイルのダウンロードする
ダウンロードした 「google-services.json」は
AndroidStudioの画面で「app」にドラッグ&ドロップで置いておく
メールでの認証を有効にする
構築 -> Authentication の「Sign-in method」タブを開く
ログイン プロバイダの項目で、「新しいプロバインダを追加」を押す
ポップアップが出てくるので、「メール」を選択
以下の二つを有効にする
・メール/パスワード
・メールリンク(パスワードなしでログイン)
Dynamic Linksでドメインを作る
AndroidSdudioで実装時に、アプリからFirebaseに認証メール送信要求を出す。
その時のパラメータにURL指定項目があり、そこで使うドメインを作成する
その時のパラメータにURL指定項目があり、そこで使うドメインを作成する
左のバーからDynamic Linksを押下(右図参照) 新しいドメインを作る。 末尾に「.page.link」を入れると無料のカスタム サブドメインとして生成できる。今回は ドメイン名は「mailloginsample.page.link」としておく 参考 |
その後、URLを認証する必要があるので
構築 -> Authentication の「Sign-in method」タブを開く
承認済みドメインの項目で、「ドメインを追加」を押し、先ほど作ったドメイン(mailloginsample.page.link)を入力する
Firebaseの準備はこれで完了!!
ドメインを作る情報が見つけられず少し手間取った...
AndroidStudio側の実装
SDK等開発環境構築
「google-services.json」の取り込みは、上で説明したので割愛
承認に必要なSDKを取り込んでいく
承認に必要なSDKを取り込んでいく
「project/build.gradle」に以下の★の1行を追加
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { google() mavenCentral() } dependencies { classpath "com.android.tools.build:gradle:7.0.3" classpath 'com.google.gms:google-services:4.3.10' //★コレ // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } task clean(type: Delete) { delete rootProject.buildDir }
「app/build.gradle」の以下の★の行を追加(バージョンは最新のものが望ましい)
plugins { : : id 'com.google.gms.google-services' // ★追加 } : : dependencies { implementation platform('com.google.firebase:firebase-bom:28.4.2')// ★追加 implementation 'com.google.firebase:firebase-analytics' // ★追加 implementation 'com.google.firebase:firebase-auth' // ★追加 implementation 'com.google.firebase:firebase-firestore' // ★追加 implementation 'com.google.android.gms:play-services-auth:19.2.0' // ★追加 : : }
画面設計
今回はテストなので1画面内に以下のViewを配置する
|
実装
①メールアドレスを入力してもらい、招待メールをもらう
招待メール送信要求はString型のメールアドレスさえあれば作れるのでメソッド化しておく
招待メールボタン押下を契機(onClickSendMail)に、ExitTextから文字列を取得しFireabseへ要求する。
/** 招待メールボタン押下イベント * Firebaseに招待メールを送信するように要求する */ public void onClickSendMail(View v) { TextView tv = findViewById(R.id.editText); requestEmail(tv.getText().toString()); } /** firebaseに招待メールを要求 */ private void requestEmail(String email) { ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder() .setUrl("https://mailloginsample.page.link") // ★ Fireabase側の実装で、dynamicLinkで作ったドメイン .setHandleCodeInApp(true) // ★ 必ずTrueでないとエラー .build(); FirebaseAuth auth = FirebaseAuth.getInstance(); auth.sendSignInLinkToEmail(email, actionCodeSettings) .addOnCompleteListener(task -> { if (task.isSuccessful()) { Toast.makeText(this, "このメールアドレスにメールを送信しました。", Toast.LENGTH_SHORT) .show(); // メールアドレスは不揮発領域に保存しておく getSharedPreferences("mail", MODE_PRIVATE).edit().putString("address", email).apply(); } else { Toast.makeText(this, String.valueOf(task.getException()), Toast.LENGTH_LONG) .show(); } }); }
ミソは21行目。
メール要求に成功したとき、入力したメールアドレスを不揮発に保存しておく。
メールを受けてリンク押下でこのアプリが立ち上がった時、新規Activity起動となる為、メアド覧が空になり再入力してもらう羽目になる。なので、ここで保存して、起動時に表示させる仕組みにする。
②メールを受信しリンク押下で本アプリを起動させる
AndroidManifest.xmlを編集することで、スマホで特定のドメインのURLへ遷移する時、本アプリが立ち上がる設定を入れておく。
<activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <!-- ★ここから追加 --> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:host="mailloginsample.page.link" android:scheme="https"/> <!-- ★ここまで --> </intent-filter> </activity>13行目が大事で、ここは先ほども設定したdynamicLinkで作ったドメイン。
これで「https://mailloginsample.page.link」から始まるRULをクリックしたら、本アプリが立ち上がるようになる。
③ログイン認証を行う
メールを受けて、メールのリンクを押下して本アプリが起動したときに限り
Intentにメールリンク情報(URI)が入っている。
メールアドレスと、このメールリンク情報の二つがあれば認証が行える。
①同様に認証をメソッド化し、認証ボタン押下契機(onClickSignIn)と合わせて以下となる
/** ログイン認証ボタン押下イベント * Firebaseにログイン認証を要求する */ public void onClickSignIn(View v) { // メールのリンクから起動したときはIntentにemailLink情報が入っている Intent intent = getIntent(); String emailLink = intent.getData().toString(); // 入力エリアからメールアドレスを取得 TextView tv = findViewById(R.id.editText); String email = tv.getText().toString(); // 認証要求 requestSignIn(email, emailLink); } /** fairebaseに認証要求 */ private void requestSignIn(String email, String emailLink) { FirebaseAuth auth = FirebaseAuth.getInstance(); if (auth.isSignInWithEmailLink(emailLink)) { auth.signInWithEmailLink(email, emailLink) .addOnCompleteListener(task -> { if (task.isSuccessful()) { AuthResult result = task.getResult(); Toast.makeText(this, "認証成功:IDは" + result.getUser().getUid(), Toast.LENGTH_LONG).show(); } else { Toast.makeText(this, String.valueOf(task.getException()), Toast.LENGTH_LONG).show(); } }); } else { Toast.makeText(this, "リンクが正しくありません。emailLink=" + emailLink, Toast.LENGTH_LONG).show(); } }このLink情報もメアド同様に不揮発に保持しておけば、
次回以降は自動で認証完了することもできる。
以上で、メールリンク認証をAndroidで実装する方法は完成!!
終わりに
上で触れていない、不揮発に書いたメアドを復活させるコードなども含めて
全体のjavaコード。Kotlinコードを以下に載せておく。
0 件のコメント:
コメントを投稿