Аутентификация пользователей с помощью Firebase и React
Узнайте, как Firebase может упростить адаптацию пользователей.
Firebase предоставляет службы аутентификации, которые позволяют легко регистрировать и входить в систему пользователей. Вы можете использовать электронную почту, пароли, номера телефонов и поставщиков удостоверений, таких как Google и Facebook.
В этом руководстве вы узнаете, как использовать аутентификацию Firebase в React для аутентификации пользователей с использованием электронной почты и пароля. Вы будете хранить собранные пользовательские данные в Firestore, облачной базе данных NoSQL, также принадлежащей Firebase.
Обратите внимание, что в этом руководстве используются Firebase v9 и React Router v6.
Создайте приложение Firebase
Чтобы подключить свое приложение к Firebase, зарегистрируйте свое приложение в Firebase, чтобы получить объект конфигурации. Это то, что вы будете использовать для инициализации Firebase в своем приложении React.
Чтобы создать приложение Firebase, выполните следующие действия.
- Перейдите в консоль Firebase и нажмите Создать проект.
- Дайте своему проекту имя и нажмите Создать, чтобы начать процесс.
- Нажмите значок Интернет (>) на странице обзора вашего проекта, чтобы зарегистрировать приложение.
- Дайте своему приложению имя по вашему выбору и нажмите Зарегистрировать приложение. Вам не нужно включать хостинг Firebase.
- Скопируйте объект конфигурации в раздел Добавить Firebase SDK.
Создать приложение React
Используйте create-react-app для создания шаблона приложения React.
npx create-react-app react-auth-firebase
Перейдите в папку и запустите приложение.
cd react-auth-firebase
npm run start
Аутентификация пользователей с помощью функций Firebase
Прежде чем использовать Firebase, установите его.
npm i firebase
Создайте новый файл firebase.js и инициализируйте Firebase.
import { initializeApp } from "firebase/app";
const firebaseConfig = {
apiKey: <api_key>,
authDomain:<auth_domain> ,
projectId: <project_id>,
storageBucket: <storage_bucket>,
messagingSenderId: <messaging_sender_id>,
appId: <app_id>
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
Используйте объект конфигурации, который вы скопировали при регистрации приложения.
Затем импортируйте модули Firebase, которые вы будете использовать.
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
} from "firebase/auth";
import { getFirestore, addDoc, collection } from "firebase/firestore";
const db = getFirestore();
const auth = getAuth();
Для аутентификации пользователей вам необходимо создать три функции: SignUp, SignIn и SignOut.
Функция signUp передает адрес электронной почты и пароль в createUserWithEmailAndPassword для регистрации нового пользователя. createUserWithEmailAndPassword возвращает данные пользователя, которые вы будете использовать для создания новой записи пользователя в базе данных.
const signUp = async (email, password) => {
try {
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
const user = userCredential.user;
await addDoc(collection(db, "users"), {
uid: user.uid,
email: user.email,
});
return true
} catch (error) {
return {error: error.message}
}
};
Обратите внимание: перед регистрацией вы не проверяете, используется ли уже адрес электронной почты, поскольку Firebase сделает это за вас.
Затем в функции signIn передайте адрес электронной почты и пароль функции signInWithEmailAndPassword , чтобы войти в систему зарегистрированного пользователя.
const signIn = async (email, password) => {
try {
const userCredential = await signInWithEmailAndPassword(
auth,
email,
password
);
const user = userCredential.user;
return true
} catch (error) {
return {error: error.message}
}
};
Функции SignUp и SignOut возвращают true в случае успеха и сообщение об ошибке в случае возникновения ошибки.
Функция SignOut довольно проста. Он вызывает функцию signOut() из Firebase.
const signOut = async() => {
try {
await signOut(auth)
return true
} catch (error) {
return false
}
};
Создание форм React
Формы входа и регистрации будут собирать адрес электронной почты и пароль пользователя.
Создайте новый компонент Signup.js и добавьте следующее.
import { useState } from "react";
import { Link } from "react-router-dom";
import { signUp } from "./firebase";
const Signup = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, seterror] = useState("");
const handleSubmit = async (e) => {
e.preventDefault();
if (password !== password2) {
seterror("Passwords do not match");
} else {
setEmail("");
setPassword("");
const res = await signUp(email, password);
if (res.error) seterror(res.error)
}
};
return (
<>
<h2>Sign Up</h2>
<div>
{error ? <div>{error}</div> : null}
<form onSubmit={handleSubmit}>
<input
type="email"
name="email"
value={email}
placeholder="Your Email"
required
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
name="password"
value={password}
placeholder="Your Password"
required
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Submit</button>
</form>
<p>
already registered? <Link to="/login">Login</Link>
</p>
</div>
</>
);
};
export default Signup;
Здесь вы создаете форму регистрации и отслеживаете адрес электронной почты и пароль, используя состояние. После отправки формы событие onSubmit запускает функцию handleSubmit(), которая вызывает функцию signUp() из firebase.js. . Если функция возвращает ошибку, обновите состояние ошибки и отобразите сообщение об ошибке.
Для формы входа создайте Signin.js и добавьте следующее.
import { useState } from "react";
import { signIn } from "./firebase";
const Login = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, seterror] = useState("");
const handleSubmit = async (e) => {
e.preventDefault();
setEmail("");
setPassword("");
const res = await signIn(email, password);
if (res.error) seterror(res.error);
};
return (
<>
{error ? <div>{error}</div> : null}
<form onSubmit={handleSubmit}>
<input
type="text"
name="email"
value={email}
placeholder="Your Email"
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
name="password"
value={password}
placeholder="Your Password"
onChange={(e) => setPassword(e.target.value)}
/>
<input type="submit" value="submit" />
</form>
</>
);
};
export default Login;
Форма входа очень похожа на страницу регистрации, за исключением того, что при отправке вызывается функция signIn().
Наконец, создайте страницу профиля. Это страница, на которую приложение будет перенаправлять пользователей после успешной аутентификации.
Создайте Profile.js и добавьте следующее.
import { signOut } from "./firebase";
const Profile = () => {
const handleLogout = async () => {
await signOut();
};
return (
<>
<h1>Profile</h1>
<button onClick={handleLogout}>Logout</button>
</>
);
};
export default Profile;
В этом компоненте у вас есть заголовок «Профиль» и кнопка выхода из системы. Обработчик onClick на кнопке запускает функцию handleLogout, которая осуществляет выход пользователя.
Создание маршрутов аутентификации
Чтобы отображать созданные вами страницы в браузере, настройте react-router-dom.
Установите react-router-dom:
npm i react-router-dom
В index.js настройте react-router-dom:
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./App";
import Login from "./Login";
import Profile from "./Profile";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<AuthProvider>
<Routes>
<Route path="/" element={<App />} />
<Route path="login" element={<Login />} />
<Route path="profile" element={<Profile />} />
</Routes>
</AuthProvider>
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
До этого момента приложение может зарегистрировать пользователя, зарегистрировать его и выйти из системы. Так как же узнать, вошел ли пользователь в систему или нет?
В следующем разделе этого руководства вы увидите, как можно использовать контекст React для отслеживания статуса аутентификации пользователя в приложении.
Управление аутентификацией с помощью React Context API
React Context — это инструмент управления состоянием, который упрощает обмен данными между приложениями. Это лучшая альтернатива детализации свойств, при которой данные передаются по дереву от родительского элемента к дочернему, пока не достигнут компонента, который в них нуждается.
Создать контекст аутентификации
В папке src добавьте файл AuthContext.js, создайте и экспортируйте AuthContext.
import { createContext } from "react";
const AuthContext = createContext();
export default AuthContext;
Затем создайте поставщика в AuthProvider.js. Это позволит компонентам использовать AuthContext.
import { getAuth, onAuthStateChanged } from "firebase/auth";
import { useState, useEffect } from 'react';
import AuthContext from './AuthContext'
const auth = getAuth()
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() => {
onAuthStateChanged(auth,(user) => {
setUser(user)
})
}, []);
return (
<AuthContext.Provider value={{ user }}>{children}</AuthContext.Provider>
);
};
Здесь вы получаете значение пользователя, используя метод onAuthStateChanged() из Firebase. Этот метод возвращает объект пользователя, если он аутентифицирует пользователя, и значение null, если это невозможно. При использовании перехватчика useEffect() значение пользователя обновляется каждый раз при изменении статуса аутентификации.
В index.js оберните маршруты AuthProvider, чтобы обеспечить доступ всех компонентов к пользователю в контексте:
import { AuthProvider } from "./AuthProvider";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<AuthProvider>
<Routes>
<Route path="/" element={<App />} />
<Route path="login" element={<Login />} />
<Route path="profile" element={<Profile />} />
</Routes>
</AuthProvider>
</BrowserRouter>
,
</React.StrictMode>,
document.getElementById("root")
);
Создание защищенных маршрутов
Чтобы защитить конфиденциальные маршруты, проверьте статус аутентификации пользователя, пытающегося перейти на защищенную страницу, например страницу профиля.
Измените Profile.js, чтобы перенаправить пользователя, если он не прошел проверку подлинности.
import { useContext } from "react";
import AuthContext from "./AuthContext";
import { useNavigate, Navigate } from "react-router-dom";
import { signOut } from "./firebase";
const Profile = () => {
const { user } = useContext(AuthContext);
const navigate = useNavigate();
const handleLogout = async () => {
await signOut();
};
if (!user) {
return <Navigate replace to="/login" />;
}
return (
<>
<h1>Profile</h1>
<button onClick={handleLogout}>Logout</button>
</>
);
};
export default Profile;
Приложение условно отображает страницу профиля, перенаправляя пользователя на страницу входа, если он не прошел проверку подлинности.
Идем дальше с аутентификацией Firebase
В этом руководстве вы использовали Firebase для аутентификации пользователей по электронной почте и паролю. Вы также создали записи пользователей в Firestore. Firebase предоставляет функции для работы с поставщиками аутентификации, такими как Google, Facebook и Twitter.