Это руководство является дополнением к статье «Как настроить аутентификацию Firebase с помощью веб-приложения React ». Во введении к этому руководству я отметил, что Firebase предлагает другие схемы аутентификации, помимо базовой аутентификации по электронной почте/паролю. Одной из таких альтернатив является аутентификация без пароля .
Аутентификация без пароля — привлекательный вариант при создании приложений. Это упрощает работу с пользователем, поскольку вашим пользователям не нужно запоминать свои пароли и, следовательно, им не придется беспокоиться о их потере. Это также облегчает разработку, поскольку нет необходимости разрабатывать логику захвата паролей или управления.
В этом руководстве вы создадите простой рабочий процесс входа/подтверждения/профиля/выхода, который реализует беспарольную аутентификацию Firebase.
Google устанавливает различные ограничения аутентификации Firebase. Если вы используете бесплатный план Spark , обратите внимание, что вы будете ограничены 5 электронными письмами со ссылками для входа в день. Хотя плана Spark может быть достаточно для целей тестирования, вам потребуется перейти на план Blaze с оплатой по мере использования, чтобы превысить этот предел.
В этом руководстве я буду ссылаться на руководство «Как настроить аутентификацию Firebase с помощью веб-приложения React» в качестве предварительного руководства , а связанный с ним проект — в качестве предварительного проекта .
Для выполнения этого руководства вам потребуется:
В руководстве по предварительным требованиям вы создали новый проект Firebase для базовой аутентификации по электронной почте и паролю. Теперь вы включите тот же проект для аутентификации без пароля. Войдите в свою учетную запись Firebase и нажмите «Перейти к консоли» .
Нажмите на свой проект аутентификации, указанный на панели управления проектами Firebase. В этом руководстве используется имя проекта my-auth-test
.
Нажмите на аутентификацию в меню левой панели.
Нажмите на вкладку «Метод входа» в главном окне.
Судя по вашим действиям в руководстве по предварительным требованиям, в таблице «Поставщики входа» уже должен отображаться адрес электронной почты и пароль в столбце «Поставщики» со статусом « Включено» . Нажмите на значок карандаша, чтобы открыть панель конфигурации поставщика электронной почты/пароля .
Нажмите на переключатель, чтобы включить ссылку на электронную почту (вход без пароля) .
Нажмите Сохранить .
Теперь ваш проект Firebase настроен для поддержки аутентификации без пароля.
Создайте новый проект React, используя желаемое имя приложения. В этом руководстве используется passwordless-auth
.
npx create-react-app passwordless-auth
Для этого руководства требуется установка трех пакетов Node.js:
Установите каждый из трех пакетов выше через npm
:
npm install firebase
npm install react-router-dom
npm install bootstrap
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, нажмите значок шестеренки рядом с «Обзор проекта» в меню левой панели. Вкладка «Общие» уже должна быть выбрана. Прокрутите вниз до раздела «Ваши приложения» , содержащего панель «Веб-приложения» . Параметр npm на панели веб-приложений уже должен быть выбран. Значения конфигурации вашего проекта будут перечислены в отображаемом блоке кода.
Приложение React будет состоять из 5 компонентов: App
, Layout
, Login
, Confirm
и Profile
.
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
reportWebVitals.js
setupTests.js
logo.svg
index.css
App.css
App.test.js
Скопируйте index.js
из необходимого проекта в папку нового проекта. В этом руководстве используется тот же файл. Если вам нужно пересобрать index.js
, см. шаг 5b.2 руководства по предварительным требованиям или скопируйте приведенный ниже блок кода.
Скопируйте Layout.jsx
из необходимого проекта в папку нового проекта. В этом руководстве используется тот же файл. Если вам нужно пересобрать Layout.jsx
, см. шаг 5d руководства по предварительным требованиям или скопируйте приведенный ниже блок кода. При желании вы можете обновить текст проекта в теге <p>
Layout.jsx
, чтобы 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
App.js
Файл App.js
во многом такой же, как и в предварительном проекте, с изменениями всего в двух строках. Чтобы облегчить создание файла, скопируйте App.js
из необходимого проекта в папку нового проекта.
Удалите следующую строку import
из файла и замените ее, как показано ниже:
// Delete this line: import Signup from "./Signup";
// Replace it with: import Confirm from "./Confirm";
Удалите из файла следующий <Route>
и замените его, как показано ниже:
// Delete this line: <Route path = "/signup" element = { <Signup></Signup> } ></Route>
// Replace it with: <Route path = "/confirm" element = { <Confirm></Confirm> } ></Route>
Сохраните 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
снова является домашним маршрутом приложения, как это было в предварительном проекте.
Login.jsx
В случае аутентификации без пароля вам, очевидно, не нужно включать поле пароля, а также вам не нужно управлять состоянием ввода пароля. Таким образом, форма входа должна содержать только адрес электронной почты пользователя.
Создайте новый файл Login.jsx
в каталоге src
.
Добавьте следующий код:
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> ) }
Login.jsx
.
После получения адреса электронной почты пользователя форма Login.jsx
отправляет электронное письмо со ссылкой для входа на его адрес с помощью метода Firebase sendSignInLinkToEmail
. В случае успеха пользователь уведомляется об отправке электронного письма. Обратите внимание, что объект actionCodeSettings
передается в качестве параметра методу sendSignInLinkToEmail
и включает URL-адрес, на который будет перенаправлен пользователь, когда он щелкнет ссылку для входа, отправленную по электронной почте. В этом случае URL-адрес сопоставляется с маршрутом /confirm
указанным в App.js
Confirm.jsx
Метод signInWithEmailLink
в Firebase используется для входа в систему пользователя, который нажал на ссылку для входа. Как вы вскоре увидите, метод принимает параметр email
, а значение email
должно соответствовать адресу электронной почты, который пользователь использовал при входе в систему через форму входа. Confirm.jsx
предоставляет пользователю форму для подтверждения его/ее адреса электронной почты и впоследствии пытается войти в систему.
Создайте новый файл Confirm.jsx
в каталоге src
.
Добавьте следующий код:
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
Confirm.jsx
.
Метод isSignInWithEmailLink
сначала проверяет, действительна ли ссылка для входа, которую использует пользователь. Если это так, для входа пользователя вызывается метод signInWithEmailLink
. Еще раз повторим: значение email
, передаваемое в метод signInWithEmailLink
, должно соответствовать адресу электронной почты, который пользователь использовал в форме входа. Обратите внимание: если пользователь является новым пользователем (т. е. он/ее входит в систему впервые), Firebase автоматически создаст пользователя в хранилище аутентификации Firebase. Это еще один пример упрощения аутентификации без пароля: создание учетной записи для новых пользователей выполняется автоматически.
Profile.jsx
Последний компонент, который вы создадите, — это Profile.jsx
. Пользователи перенаправляются на этот компонент после успешного входа в систему через Confirm.jsx
. Маршрут приветствует пользователя адресом электронной почты и предоставляет кнопку для выхода из системы. После выхода из системы пользователь перенаправляется обратно к компоненту Login
.
Создайте новый файл Profile.jsx
в каталоге src
.
Добавьте следующий код:
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
Profile.jsx
.Запустите приложение React:
npm start
locahost:3000
в своем браузере, если ваш браузер не запускается автоматически. Вы должны увидеть форму Login
.
Введите адрес электронной почты, который вы хотите использовать для входа, и нажмите «Отправить» . Если отправка прошла успешно, отобразится уведомление о том, что на ваш адрес электронной почты было отправлено письмо со ссылкой для входа.
Sign in to project-1078604952662
, где 13-значная числовая последовательность представляет собой messagingSenderId
вашего проекта Firebase (см. шаг 3 этого руководства). В разделе «Необязательно» ниже я объясню, как вы можете изменить имя вашего проекта Firebase, чтобы оно отображалось «удобным для пользователя» именем в электронных письмах со ссылкой для входа. А пока откройте электронное письмо со ссылкой для входа и нажмите ссылку для входа. Вы будете перенаправлены на форму Confirm
.
Введите адрес электронной почты, который вы использовали при входе в систему, в форме Confirm
. Нажмите «Подтвердить» . Если подтверждение пройдет успешно, вы будете перенаправлены на страницу Profile
.
Нажмите кнопку «Выход» на странице Profile
, чтобы выйти. Если выход пройдет успешно, вы вернетесь к форме Login
.
Приведенные выше шаги отражают рабочий процесс приложения.
Вы можете изменить название своего проекта, чтобы в электронных письмах со ссылкой для входа, отправленных Firebase, отображалось «удобное для пользователя» имя вместо, например, project-1078604952662
. Войдите в свою учетную запись Firebase и нажмите «Перейти к консоли» .
Аутентификация без пароля становится все более популярным выбором среди разработчиков приложений, и это вполне понятно. Помимо очевидного преимущества, заключающегося в устранении необходимости управлять паролями, также нет необходимости в проверке электронной почты, поскольку процесс отправки ссылки для входа сам по себе является проверкой.
Как и в случае с обязательным проектом, реализация здесь является базовой. Вы можете рассмотреть возможность простых улучшений, таких как:
Блокирование/внесение в черный список определенных доменов адресов электронной почты (т. е. доменов, рассылающих спам).
Локальное сохранение адреса электронной почты, введенного пользователем на странице Login
, и проверка существования адреса электронной почты на странице Confirm
. При таком подходе, если пользователь нажимает ссылку для входа на том же устройстве, где он/она получил доступ к странице Login
, ему/ей не нужно будет снова вводить свой адрес электронной почты на странице Confirm
, поскольку он будет восстановлен. из локального хранилища. Это обеспечивает еще более удобный пользовательский интерфейс.
Вы можете узнать больше о беспарольной аутентификации Firebase в официальной документации .