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へ遷移する時、本アプリが立ち上がる設定を入れておく。
13行目が大事で、ここは先ほども設定したdynamicLinkで作ったドメイン。
- <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>
これで「https://mailloginsample.page.link」から始まるRULをクリックしたら、本アプリが立ち上がるようになる。
③ログイン認証を行う
メールを受けて、メールのリンクを押下して本アプリが起動したときに限り
Intentにメールリンク情報(URI)が入っている。
メールアドレスと、このメールリンク情報の二つがあれば認証が行える。
①同様に認証をメソッド化し、認証ボタン押下契機(onClickSignIn)と合わせて以下となる
このLink情報もメアド同様に不揮発に保持しておけば、
- /** ログイン認証ボタン押下イベント
- * 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();
- }
- }
次回以降は自動で認証完了することもできる。
以上で、メールリンク認証をAndroidで実装する方法は完成!!
終わりに
上で触れていない、不揮発に書いたメアドを復活させるコードなども含めて
全体のjavaコード。Kotlinコードを以下に載せておく。
0 件のコメント:
コメントを投稿