paint-brush
如何使用 React Web 应用程序设置 Firebase 无密码身份验证经过@pictureinthenoise
1,964 讀數
1,964 讀數

如何使用 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 身份验证的补充。在该指南的介绍中,我注意到 Firebase 提供了除基本电子邮件/密码身份验证之外的其他身份验证方案。这些替代方案之一是无密码身份验证


在构建应用程序时,无密码身份验证是一个有吸引力的选择。它简化了用户体验,因为您的用户无需记住他们的密码,因此也不必担心丢失密码。它还简化了开发体验,因为无需设计任何密码捕获或管理逻辑。


在本指南中,您将构建一个简单的登录/确认/个人资料/注销工作流程来实现 Firebase 的无密码身份验证。

在你开始之前

Google 设置了各种 Firebase 身份验证限制。如果您使用免费的Spark计划,请注意,您每天最多只能发送 5 封登录链接电子邮件。虽然 Spark 计划可能足以满足测试目的,但您需要升级到即用即付Blaze计划才能超过此限制。


先决条件

在本指南中,我将参考如何使用 React Web 应用程序设置 Firebase 身份验证指南作为先决条件指南,并将关联的项目作为先决项目

要完成本指南,您需要:


  • 已完成先决条件指南,包括所有先决条件。


第 1 步 - 在您的 Firebase 项目中启用无密码身份验证

在先决条件指南中,您创建了一个用于基本电子邮件/密码身份验证的新 Firebase 项目。现在,您将为同一项目启用无密码身份验证。登录您的Firebase 帐户并点击Go to Console


  1. 单击 Firebase 项目仪表板上列出的身份验证项目。本指南使用项目名称my-auth-test

  2. 单击左侧面板菜单中的身份验证

  3. 单击主窗口中的登录方法选项卡。

  4. 根据您在先决条件指南中的工作,登录提供程序表应该已在提供程序列下显示电子邮件/密码,状态为Enabled 。单击铅笔图标打开电子邮件/密码提供商的配置面板。

  5. 单击开关以启用电子邮件链接(无密码登录)

  6. 单击“保存”


您的 Firebase 项目现已配置为支持无密码身份验证。

第 2 步 - 创建一个新的 React 项目并安装包

步骤 2a - 创建一个新的 React 项目

使用您所需的应用程序名称创建一个新的 React 项目。本指南使用passwordless-auth


 npx create-react-app passwordless-auth


步骤 2b - 安装软件包

本指南需要安装 3 个 Node.js 包:



通过npm安装上述三个软件包:


 npm install firebase


 npm install react-router-dom


 npm install bootstrap


第 3 步 - 从先决项目复制firebase.js

在必备项目中,您创建了一个firebase.js文件,该文件使用 Firebase 项目配置数据来创建 Firebase 身份验证服务的实例。您的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 应用程序将由 5 个组件组成: AppLayoutLoginConfirmProfile

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.jsLayout.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文件与必备项目中的文件基本相同,仅更改了两行。为了便于构建文件,请将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 身份验证存储中创建该用户。这是无密码身份验证提供的简化体验的另一个示例:自动处理新用户的帐户创建。

步骤 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 帐户并点击Go to Console


  1. 单击 Firebase 项目仪表板上列出的身份验证项目。
  2. 单击左侧面板菜单中“项目概述”旁边的齿轮图标。应已选择“常规”选项卡。
  3. 向下滚动到“您的项目”部分中的“面向公众的名称”选项。
  4. 单击铅笔图标并根据需要修改项目名称。
  5. 单击“保存” 。您的登录链接电子邮件现在将显示更新的项目名称。

结论和后续步骤

无密码身份验证似乎是应用程序开发人员中越来越流行的选择,这是可以理解的。除了无需管理密码的明显优势之外,还不需要电子邮件验证,因为发送登录链接的过程本身就是一种验证。


与先决项目一样,这里的实施是基础的。您可以考虑简单的增强功能,例如:


  • 将特定电子邮件地址域(即常见的垃圾邮件域)阻止/列入黑名单。

  • 本地存储用户在Login页面输入的电子邮件地址,并在Confirm页面检查该电子邮件地址是否存在。通过这种方法,如果用户在访问Login页面的同一设备上单击登录链接,则他/她无需在Confirm页面上再次输入他/她的电子邮件地址,因为该地址将被恢复来自本地存储。这提供了更加顺畅的用户体验。


您可以通过官方文档了解有关 Firebase 无密码身份验证的更多信息。