paint-brush
React Web アプリケーションで Firebase パスワードレス認証を設定する方法@pictureinthenoise
2,013 測定値
2,013 測定値

React Web アプリケーションで Firebase パスワードレス認証を設定する方法

Picture in the Noise17m2023/09/24
Read on Terminal Reader

長すぎる; 読むには

パスワードレス認証は、アプリケーションを構築する際の魅力的なオプションです。これにより、ユーザー エクスペリエンスと開発者のエクスペリエンスが簡素化されます。このチュートリアルでは、単純な React Web アプリケーションを使用して Firebase パスワードなし認証を実装する手順を説明します。
featured image - React Web アプリケーションで Firebase パスワードレス認証を設定する方法
Picture in the Noise HackerNoon profile picture
0-item

導入

このガイドは、「React Web アプリケーションで Firebase Authentication を設定する方法」の補足です。このガイドの導入部分で、Firebase が基本的なメール/パスワード認証以外の認証スキームを提供していることに注意しました。それらの代替手段の 1 つは、パスワードレス認証です。


パスワードレス認証は、アプリケーションを構築する際の魅力的なオプションです。ユーザーはパスワードを覚えておく必要がなく、パスワードを紛失することを心配する必要もないため、ユーザー エクスペリエンスが簡素化されます。また、パスワードのキャプチャや管理ロジックを設計する必要がないため、開発エクスペリエンスも容易になります。


このガイドでは、Firebase のパスワードなしの認証を実装する、単純なログイン/確認/プロファイル/ログアウト ワークフローを構築します。

あなたが始める前に

Google は Firebase Authentication のさまざまな制限を設定しています。無料のSparkプランを使用している場合は、サインイン リンク メールが 1 日あたり 5 通に制限されることに注意してください。 Spark プランはテスト目的には十分かもしれませんが、この制限を超えるには従量課金制のBlazeプランにアップグレードする必要があります。


前提条件

このガイド全体を通じて、 「React Web アプリケーションで Firebase Authentication を設定する方法」ガイドを前提条件ガイドとして参照し、関連するプロジェクトを前提条件プロジェクトとして参照します。

このガイドを完了するには、次のものが必要です。


  • すべての前提条件を含む前提条件ガイドを完了している。


ステップ 1 - Firebase プロジェクトでパスワードレス認証を有効にする

前提条件ガイドでは、基本的なメール/パスワード認証用の新しい Firebase プロジェクトを作成しました。次に、同じプロジェクトでパスワードなしの認証を有効にします。 Firebase アカウントにログインし、 [コンソールに移動]をクリックします。


  1. Firebase プロジェクト ダッシュボードにリストされている認証プロジェクトをクリックします。このガイドでは、プロジェクト名my-auth-testを使用します。

  2. 左側のパネルメニューで「認証」をクリックします。

  3. メイン ウィンドウで[サインイン方法]タブをクリックします。

  4. 前提条件ガイドでの作業により、 「サインイン プロバイダー」テーブルの「プロバイダー」列の下に「電子メール/パスワード」がすでに「有効」のステータスで表示されているはずです。鉛筆アイコンをクリックして、電子メール/パスワードプロバイダーの構成パネルを開きます。

  5. トグルをクリックして、電子メール リンク (パスワードなしのサインイン)を有効にします。

  6. 「保存」をクリックします。


これで、Firebase プロジェクトがパスワードなしの認証をサポートするように構成されました。

ステップ 2 - 新しい React プロジェクトの作成とパッケージのインストール

ステップ 2a - 新しい React プロジェクトの作成

希望のアプリケーション名を使用して新しい React プロジェクトを作成します。このガイドでは、 passwordless-authを使用します。


 npx create-react-app passwordless-auth


ステップ 2b - パッケージのインストール

このガイドでは、3 つの Node.js パッケージのインストールが必要です。



上記の 3 つのパッケージをそれぞれnpm経由でインストールします。


 npm install firebase


 npm install react-router-dom


 npm install bootstrap


ステップ 3 - 前提条件プロジェクトからfirebase.jsをコピーする

前提条件プロジェクトでは、Firebase プロジェクト構成データを使用して Firebase Authentication サービスのインスタンスを作成するfirebase.jsファイルを作成しました。 firebase.jsファイルは、Firebase プロジェクト設定値を含む次の構造になっている必要があります。


 import { initializeApp } from "firebase/app"; import { getAuth } from "firebase/auth"; const firebaseConfig = { apiKey: "AIzaSyDiUlY68W9Li_0EIkmdGdzD7nvqCT9kHnY", authDomain: "my-auth-test-fbd48.firebaseapp.com", projectId: "my-auth-test-fbd48", storageBucket: "my-auth-test-fbd48.appspot.com", messagingSenderId: "1078604952662", appId: "1:1078604952662:web:5d0b908439cfb5684ab7f7" } const app = initializeApp(firebaseConfig); const auth = getAuth(app); export { auth }


firebase.js新しい React プロジェクト フォルダーにコピーします。


Firebase プロジェクトの構成を確認する必要がある場合は、左側のパネル メニューで[プロジェクトの概要]の横にある歯車アイコンをクリックします。 [全般]タブがすでに選択されているはずです。 [Web アプリ]パネルを含む[アプリ]セクションまで下にスクロールします。 Web アプリパネル内のnpmオプションはすでに選択されているはずです。プロジェクトの構成値が、表示されたコード ブロックにリストされます。


ステップ 4 - React アプリケーションの構築

ステップ 4a - React アプリケーション コンポーネントの概要

React アプリケーションは、 AppLayoutLoginConfirmProfileの 5 つのコンポーネントで構成されます。

App


  • Appコンポーネントは、ルーティングを含むアプリケーション全体の構造を定義します。

Layout

  • Layoutコンポーネントは、すべてのルートにわたって一貫性を保つアプリケーション マークアップを指定します。

Login

  • アプリケーションへのユーザーのエントリ ポイントはログイン フォームです。
  • ユーザーが自分の電子メール アドレスを使用してログインしようとすると、サインイン リンクが記載された電子メールがその電子メール アドレスに送信されます。

Confirm

  • ユーザーがサインイン リンクをクリックすると、 Confirmページにルーティングされます。
  • このページでは、ユーザーがログイン時に使用した電子メール アドレスを確認するように求められます。

Profile

  • ユーザーは、電子メール アドレスを確認した後、 Profileページにルーティングされます。
  • ユーザーは、 Profileページのログアウト ボタンをクリックして、自分のアカウントからログアウトできます。

最終的なsrcディレクトリには次のファイルが含まれます。


 src |__ index.js |__ firebase.js // Copied from prerequisite project in Step 3. |__ App.js |__ Layout.jsx |__ Login.jsx |__ Confirm.jsx |__ Profile.jsx


ステップ 4b - React プロジェクト テンプレートをクリーンアップし、前提条件プロジェクトからファイルをコピーする

  1. 前提条件ガイドのステップ 5b.1 で説明されているように、React プロジェクト テンプレートから同じファイルを削除できます。 React プロジェクトから次のファイルを削除します。
  • reportWebVitals.js
  • setupTests.js
  • logo.svg
  • index.css
  • App.css
  • App.test.js
  1. 前提条件プロジェクトから新しいプロジェクト フォルダーにindex.jsをコピーします。このガイドでは同じファイルを使用します。 index.jsを再構築する必要がある場合は、前提条件ガイドのステップ 5b.2 を参照するか、以下のコード ブロックをコピーしてください。

  2. Layout.jsx前提条件プロジェクトから新しいプロジェクト フォルダーにコピーします。このガイドでは同じファイルを使用します。 Layout.jsxを再構築する必要がある場合は、前提条件ガイドのステップ 5d を参照するか、以下のコード ブロックをコピーしてください。必要に応じて、 Layout.jsx<p>タグ内のプロジェクト テキストをReact With Firebase Passwordless Authenticationまたは任意のタイトルに更新することができます。


index.jsおよびLayout.jsxファイルは次のようになります。


 // index.js import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import "bootstrap/dist/css/bootstrap.min.css"; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> );


 // Layout.jsx import { Outlet } from "react-router-dom"; const Layout = () => { return( <div className = "container-fluid"> <div className = "row justify-content-center mt-3"> <div className = "col-md-4 text-center"> <p className = "lead">React With Firebase Passwordless Authentication</p> </div> <Outlet /> </div> </div> ) } export default Layout


ステップ 4c - App.jsの構築

App.jsファイルは前提条件プロジェクトのファイルとほぼ同じですが、変更点は 2 行のみです。ファイルの構築を容易にするために、前提条件プロジェクトから新しいプロジェクト フォルダーにApp.jsをコピーします。

  1. ファイルから次のimport行を削除し、以下のように置き換えます。


 // Delete this line: import Signup from "./Signup";


 // Replace it with: import Confirm from "./Confirm";


  1. ファイルから次の<Route>を削除し、以下のように置き換えます。


 // Delete this line: <Route path = "/signup" element = { <Signup></Signup> } ></Route>


 // Replace it with: <Route path = "/confirm" element = { <Confirm></Confirm> } ></Route>


  1. App.jsを保存します。


完全なファイルは次のようになります。


 import Layout from "./Layout"; import Login from "./Login"; import Confirm from "./Confirm"; import Profile from "./Profile"; import { BrowserRouter, Routes, Route } from "react-router-dom"; const App = () => { return ( <BrowserRouter> <Routes> <Route path = "/" element = { <Layout></Layout> }> <Route index element = { <Login></Login> }></Route> <Route path = "/confirm" element = { <Confirm></Confirm> } ></Route> <Route path = "/profile" element = { <Profile></Profile> } ></Route> </Route> </Routes> </BrowserRouter> ) } export default App


前提条件プロジェクトの場合と同様に、 Loginコンポーネントが再びアプリケーションのホーム ルートになることに注意してください。


ステップ 4d - Login.jsxのビルド

パスワードレス認証の場合、明らかにパスワード フィールドを含める必要はなく、パスワード入力の状態を管理する必要もありません。したがって、ログイン フォームはユーザーの電子メール アドレスを取得するだけで済みます。


  1. srcディレクトリに新しいLogin.jsxファイルを作成します。

  2. 次のコードを追加します。


 import { useState } from "react"; import { auth } from "./firebase"; import { sendSignInLinkToEmail } from "firebase/auth"; const Login = () => { const [email, setEmail] = useState(""); const [notice, setNotice] = useState(""); const actionCodeSettings = { url: "http://localhost:3000/confirm", handleCodeInApp: true } const callSendSignInLinkToEmail = (e) => { e.preventDefault(); sendSignInLinkToEmail(auth, email, actionCodeSettings) .then(() => { setNotice("An email was sent to your email address. Click the link in the email to login."); }) .catch((error) => { setNotice("An error occurred when sending a login link to your email address: ", error.name); }) } return( <div className = "container"> <div className = "row justify-content-center"> <form className = "col-md-4 mt-3 pt-3 pb-3"> { "" !== notice && <div className = "alert alert-warning" role = "alert"> { notice } </div> } <div className = "form-floating mb-3"> <input type = "email" className = "form-control" id = "exampleInputEmail" placeholder = "[email protected]" value = { email } onChange = { (e) => setEmail(e.target.value) }></input> <label htmlFor = "exampleInputEmail" className = "form-label">Email address</label> </div> <div className = "d-grid"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => callSendSignInLinkToEmail(e)}>Submit</button> </div> </form> </div> </div> ) }
  1. Login.jsxを保存します。


ユーザーのメール アドレスを取得すると、 Login.jsxフォームは、Firebase のsendSignInLinkToEmailメソッドを介して、サインイン リンクを含むメールをユーザーのアドレスに送信します。成功すると、電子メールが送信されたことがユーザーに通知されます。 actionCodeSettingsオブジェクトはパラメーターとしてsendSignInLinkToEmailメソッドに渡され、ユーザーが電子メールで送信されたサインイン リンクをクリックしたときにルーティングされる URL が含まれていることに注意してください。この場合、URL はApp.jsで指定された/confirmルートにマップされます。


ステップ 4e - Confirm.jsxをビルドする

Firebase のsignInWithEmailLinkメソッドは、サインイン リンクをクリックしたユーザーをサインインするために使用されます。すぐにわかるように、このメソッドはemailパラメーターを受け取り、 emailの値は、ユーザーがログイン フォーム経由でログインするときに使用した電子メール アドレスと一致する必要があります。 Confirm.jsx 、ユーザーに電子メール アドレスを確認するためのフォームを表示し、その後ユーザーのサインインを試みます。


  1. srcディレクトリに新しいConfirm.jsxファイルを作成します。

  2. 次のコードを追加します。


 import { useState } from "react"; import { auth } from "./firebase"; import { isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth"; import { useNavigate } from "react-router-dom"; const Confirm = () => { const navigate = useNavigate(); const [email, setEmail] = useState(""); const [notice, setNotice] = useState(""); const callSignInWithEmailLink = (e) => { e.preventDefault(); if (isSignInWithEmailLink(auth, window.location.href)) { signInWithEmailLink(auth, email, window.location.href) .then(() => { navigate("/profile"); }) .catch((error) => { setNotice("An occurred during sign in: ", error.name); }) } } return( <div className = "container"> <div className = "row justify-content-center"> <form className = "col-md-4 mt-3 pt-3 pb-3"> { "" !== notice && <div className = "alert alert-warning" role = "alert"> { notice } </div> } <div className = "form-floating mb-3"> <input type = "email" className = "form-control" id = "exampleConfirmEmail" placeholder = "[email protected]" value = { email } onChange = { (e) => setEmail(e.target.value) }></input> <label htmlFor = "exampleConfirmEmail" className = "form-label">Please confirm your email address</label> </div> <div className = "d-grid"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => callSignInWithEmailLink(e)}>Confirm</button> </div> </form> </div> </div> ) } export default Confirm
  1. Confirm.jsxを保存します。


isSignInWithEmailLinkメソッドは、まずユーザーが使用しているサインイン リンクが有効かどうかを確認します。有効である場合、 signInWithEmailLinkメソッドが呼び出され、ユーザーがサインインします。繰り返しになりますが、 signInWithEmailLinkメソッドに渡されるemail値は、ユーザーがログイン フォームで使用した電子メール アドレスと一致する必要があります。ユーザーが新規ユーザー(つまり、初めてサインインする)の場合、Firebase は Firebase Authentication ストアにユーザーを自動的に作成することに注意してください。これは、パスワードなしの認証によって提供される簡素化されたエクスペリエンスのもう 1 つの例です。新しいユーザーのアカウント作成は自動的に処理されます。

ステップ 4f - Profile.jsxの構築

最後に構築するコンポーネントはProfile.jsxです。ユーザーは、 Confirm.jsx経由でサインインに成功すると、このコンポーネントにルーティングされます。ルートはユーザーを電子メール アドレスで歓迎し、ログアウトするボタンを提供します。ログアウトすると、ユーザーはLoginコンポーネントに戻されます。

  1. srcディレクトリに新しいProfile.jsxファイルを作成します。

  2. 次のコードを追加します。


 import { auth } from "./firebase"; import { signOut } from "firebase/auth"; import { useNavigate } from "react-router-dom"; const Profile = () => { const navigate = useNavigate(); const logoutUser = async (e) => { e.preventDefault(); await signOut(auth); navigate("/"); } return( <div className = "container"> <div className = "row justify-content-center"> <div className = "col-md-4 text-center"> <p>Welcome <em className = "text-decoration-underline">{ auth.currentUser.email }</em>. You are logged in!</p> <div className = "d-grid gap-2"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => logoutUser(e)}>Logout</button> </div> </div> </div> </div> ) } export default Profile
  1. Profile.jsxを保存します。

ステップ 5 - アプリケーションのテスト

  1. React アプリケーションを起動します。


 npm start


  1. ブラウザが自動的に起動しない場合は、ブラウザでlocahost:3000に移動します。 Loginフォームが表示されるはずです。

ログインフォーム。


  1. サインインに使用する電子メールを入力し、 [送信]をクリックします。送信が成功すると、サインイン リンクを含む電子メールが電子メール アドレスに送信されたという通知が表示されます。


ログインフォームにメールアドレスを入力します。



電子メール サインイン リンクが通知を送信しました。


  1. メール アカウントにログインし、Firebase サインイン リンクのメールを探します。件名はSign in to project-1078604952662のようなものにする必要があります。ここで、13 桁の数字シーケンスは Firebase プロジェクトのmessagingSenderIdを表します (このガイドのステップ 3 を参照)。以下の「オプション」セクションでは、Firebase プロジェクト名を変更して、サインイン リンク メールに「ユーザー フレンドリーな」名前を表示する方法を説明します。ここでは、サインイン リンク電子メールを開いて、サインイン リンクをクリックします。 Confirmフォームに移動します。

Firebase サインイン リンク メールのサンプル。


  1. サインイン時に使用した電子メール アドレスをConfirmフォームに入力します。 「確認」をクリックします。確認が成功すると、 Profileページに移動します。


メールアドレス確認フォーム。



サインインに成功した後のプロフィール ページ。


  1. サインアウトするには、 Profileページの「ログアウト」ボタンをクリックします。サインアウトが成功すると、 Loginフォームに戻ります。


上記の手順は、アプリケーションのワークフローをキャプチャします。

オプション: プロジェクト名の変更

Firebase から送信されるサインイン リンク メールに、 project-1078604952662などの代わりに「ユーザー フレンドリーな」名前が表示されるように、プロジェクト名を変更できます。 Firebase アカウントにログインし、 [コンソールに移動]をクリックします。


  1. Firebase プロジェクト ダッシュボードにリストされている認証プロジェクトをクリックします。
  2. 左側のパネル メニューで、 [プロジェクトの概要]の横にある歯車アイコンをクリックします。 [全般]タブがすでに選択されているはずです。
  3. 「プロジェクト」セクションの「公開名」オプションまで下にスクロールします。
  4. 鉛筆アイコンをクリックし、必要に応じてプロジェクト名を変更します。
  5. 「保存」をクリックします。サインイン リンクの電子メールには、更新されたプロジェクト名が表示されます。

結論と次のステップ

パスワードレス認証は、アプリケーション開発者の間でますます一般的な選択肢になっているようで、当然のことです。パスワードを管理する必要がないという明らかな利点に加えて、サインイン リンクを送信するプロセス自体が検証であるため、電子メールによる検証も必要ありません。


前提条件のプロジェクトと同様に、ここでの実装は基本的なものです。次のような単純な機能拡張を検討することもできます。


  • 特定の電子メール アドレス ドメイン (つまり、一般的なスパム電子メール ドメイン) をブロック/ブラックリストに登録します。

  • Loginページでユーザーが入力した電子メール アドレスをローカルに保存し、 Confirmページで電子メール アドレスの存在を確認します。このアプローチでは、ユーザーがLoginページにアクセスしたのと同じデバイスでサインイン リンクをクリックした場合、電子メール アドレスは回復されるため、 Confirmページで再度入力する必要がなくなります。ローカルストレージから。これにより、さらにスムーズなユーザー エクスペリエンスが提供されます。


Firebase Passwordless Authentication の詳細については、公式ドキュメントを参照してください。