это часть 2 к процессу настройки здесь
Файлы курса этого руководства по начальному коммиту + добавление файлов курса по аутентификации
Первым шагом будет настройка маршрутов react-router-dom,
import React from 'react';
import './App.css';
import { Routes, Route } from "react-router-dom";
import { BrowserRouter } from 'react-router-dom';
import { Toolbar } from './components/Toolbar/Toolbar';
import { Project } from './components/Projects/Project';
import { Home } from './components/Home/Home';
function App() {
return (
<div className="h-screen w-screen overflow-x-hidden ">
<BrowserRouter>
<div className="fixed top-[0px] right-1 w-full z-30">
<Toolbar />
</div>
<div className="w-full h-full mt-16 ">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/project" element={<Project />} />
</Routes>
</div>
</BrowserRouter>
</div>
);
}
export default App;
Добавление двух маршрутов, home.tsx и projects.tsx. Заметьте, toolbar.txt не нуждается в маршруте, так как он будет доступен везде, что делает его хорошим местом для размещения картинки профиля пользователя.
import React from 'react'
import { GrHome } from "react-icons/gr";
import { IconContext } from "react-icons/lib";
import { Link} from "react-router-dom";
import { FaUserCircle } from 'react-icons/fa';
import { useAuthSignOut} from '@react-query-firebase/auth';
import { auth } from '../../firebase/firebaseConfig';
import { User } from 'firebase/auth';
interface ToolbarProps {
user?:User|null
}
export const Toolbar: React.FC<ToolbarProps> = ({user}) => {
const mutation = useAuthSignOut(auth);
const userImg =user?.photoURL;
const image =userImg?userImg:'https://picsum.photos/id/237/100/100'
return (
<div className='w-full bg-slate-500 h-16'>
<IconContext.Provider value={{ size: "25px", className: "table-edit-icons" }} >
<div className='flex flex-grow flex-3'>
<div className='m-1 w-full p-3 bg-slate-800'>
<Link to="/"><GrHome /></Link>
</div>
<div className='m-1 w-full p-3 bg-slate-600'>
<Link to="/project">Project</Link>
</div>
<div className='m-1 w-fit p-3 bg-slate-700'>
{!user?<FaUserCircle />
:<img
// @ts-ignore
src={image}
alt={'no'}
onClick={()=>{mutation.mutate()}}
className="rounded-[50%] h-full w-[70px]"
/>}
</div>
</div>
</IconContext.Provider>
</div>
);
}
Поскольку это приложение должно знать, кто есть кто, чтобы отображать соответствующие данные, нам нужно будет защитить маршруты, чтобы они показывались только при авторизации, иначе перенаправляли на страницу входа.
import { Navigate } from 'react-router-dom';
//@ts-ignore
export const ProtectedRoute = ({ user, children }) => {
if (!user) {
return <Navigate to="/login" replace />;
}
return children;
};
Поэтому мы обернем наши маршруты с помощью вышеуказанного компонента
import React from "react";
import "./App.css";
import { Routes, Route} from "react-router-dom";
import { BrowserRouter} from "react-router-dom";
import { Toolbar } from "./components/Toolbar/Toolbar";
import { Project } from "./components/Projects/Project";
import { Home } from "./components/Home/Home";
import { useAuthUser } from "@react-query-firebase/auth";
import { auth } from "./firebase/firebaseConfig";
import { Login } from "./components/auth/Login";
import { ProtectedRoute } from "./components/auth/PrivateRoutes";
function App() {
const user= {}
return (
<div className="h-screen w-screen overflow-x-hidden ">
<BrowserRouter>
<div className="fixed top-[0px] right-1 w-full z-30">
<Toolbar user={user} />
</div>
<div className="w-full h-full mt-16 ">
<Routes>
<Route
path="/"
element={
<ProtectedRoute user={user}>
<Home />
</ProtectedRoute>
}
/>
<Route
path="/project"
element={
<ProtectedRoute user={user}>
<Project />
</ProtectedRoute>
}
/>
{/* @ts-ignore */}
<Route path="/login" element={<Login user={user} />} />
</Routes>
</div>
</BrowserRouter>
</div>
);
}
export default App;
Мы также добавили маршрут авторизации.
Настройка части аутентификации довольно проста, в файле firebaseConfig.ts экспортируйте auth из getAuth().
import { initializeApp } from "firebase/app";
import { getAuth} from "firebase/auth";
const firebaseConfig = {
//your firebase app credentials go here
};
const app = initializeApp(firebaseConfig);
export const provider = new GoogleAuthProvider();
export const auth = getAuth(app)
и используя хуки react-query-firebase мы можем запросить состояние аутентификации всего одной строкой
const query = useAuthUser("user", auth);
const user = query.data;
if (query.isFetching) {
return <div className="w-full h-full flex-center ">Loading...</div>;
}
и передать объект пользователя во все дочерние компоненты, которым он нужен в app.tsx
для добавления пользователя я выбрал google signinwithRedirect
import { GoogleAuthProvider, signInWithRedirect } from "firebase/auth";
import { auth} from "../../firebase/firebaseConfig";
const provider = new GoogleAuthProvider();
provider.addScope('https://mail.google.com/');
export const loginUser= () => {
signInWithRedirect(auth, provider)
.then((result:any) => {
console.log("sign in successful result === ",result)
// The signed-in user info.
const user = result.user;
}).catch((error) => {
// Handle Errors here.
console.log("sign in error === ",error)
});
}
в репозитории вы также заметите, что вы можете выйти из системы по нажатию на пикчу профиля
используя хук
затем вызвать
при нажатии на картинку профиля
и это все для аутентификации в следующей части мы начнем функциональную часть с firestore
ссылки:
react-query-firebase auth
firebase auth с помощью google
настройка эмулятора firebase для тестирования