[英]Unable to prevent user to go back to login page after successfully logging in
我的反應應用程序有兩個問題,我認為它們是相互關聯的:
我認為這些問題與ProtectedRoute
組件有關。 這是我的代碼:
firebase.utils.js:
import { initializeApp } from "firebase/app";
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
onAuthStateChanged,
} from "firebase/auth";
import { getFirestore, doc, getDoc, setDoc } from "firebase/firestore";
// Web app's Firebase configuration
const firebaseConfig = {
apiKey: "XXXXXXX",
authDomain: "XXXXXXX",
projectId: "XXXXXXX",
storageBucket: "XXXXXXX",
messagingSenderId: "XXXXXXX",
appId: "XXXXXXX",
measurementId: "XXXXXXX",
};
const firebaseApp = initializeApp(firebaseConfig);
export const auth = getAuth();
export const db = getFirestore();
export const createAuthUserWithEmailAndPassword = async (email, password) => {
if (!email || !password) return;
return await createUserWithEmailAndPassword(auth, email, password);
};
export const signInAuthUserWithEmailAndPassword = async (email, password) => {
if (!email || !password) return;
return await signInWithEmailAndPassword(auth, email, password);
};
export const signOutUser = async () => await signOut(auth);
export const onAuthStateChangedListener = (callback) =>
onAuthStateChanged(auth, callback);
登錄-forms.jsx:
import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { Container, Form, Button } from "react-bootstrap";
import { ToastContainer, toast } from "react-toastify";
import { signInAuthUserWithEmailAndPassword } from "../../utils/firebase/firebase.utils";
import loginImg from "../../login.png";
import "./sign-in-form.scss";
import "react-toastify/dist/ReactToastify.css";
const defaultFormFields = {
email: "",
password: "",
};
const SignInForm = () => {
const [formFields, setFormFields] = useState(defaultFormFields);
const { email, password } = formFields;
const navigate = useNavigate();
const resetFormFields = () => {
setFormFields(defaultFormFields);
};
const hadleSubmit = async (event) => {
event.preventDefault();
try {
await signInAuthUserWithEmailAndPassword(email, password);
resetFormFields();
navigate("/playground");
} catch (error) {
switch (error.code) {
case "auth/wrong-password":
toast.error("Incorrect password for email", {
position: toast.POSITION.TOP_CENTER,
});
break;
case "auth/user-not-found":
toast.error("No user associated with this email", {
position: toast.POSITION.TOP_CENTER,
});
break;
default:
console.log(error);
}
}
};
const handleChange = (event) => {
const { name, value } = event.target;
setFormFields({ ...formFields, [name]: value });
};
return (
<Container id="main-container" className="d-grid h-100">
<ToastContainer />
<Form
id="sign-in-form"
className="text-center w-300"
onSubmit={hadleSubmit}
>
<img className="mb-3 mt-3 sign-in-img" src={loginImg} alt="login" />
<Form.Group className="mb-3" controlId="sign-in-email-address">
<Form.Control
className="position-relative"
type="email"
size="lg"
placeholder="Email"
autoComplete="username"
onChange={handleChange}
name="email"
value={email}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="sign-in-password">
<Form.Control
className="position-relative"
type="password"
size="lg"
placeholder="Password"
onChange={handleChange}
name="password"
value={password}
/>
</Form.Group>
<div className="mb-3">
<Link to="/login/reset">Reset password</Link>
</div>
<div className="d-grid">
<Button variant="primary" size="lg" type="submit">
Login
</Button>
</div>
</Form>
</Container>
);
};
export default SignInForm;
protectedRoute.jsx - 我在這里包含了導航欄(導航組件),因為導航欄必須只出現在受保護的頁面上:
import { useContext } from "react";
import { Navigate, Outlet } from "react-router-dom";
import { UserContext } from "../../../contexts/user.context";
import Navigation from "../../../routes/navigation/navigation";
const ProtectedRoute = () => {
const { currentUser } = useContext(UserContext);
if (!currentUser) return <Navigate to="/auth" />;
return (
<div>
<Navigation />
<Outlet />
</div>
);
};
export default ProtectedRoute;
用戶上下文.jsx:
import { createContext, useState, useEffect } from "react";
import { onAuthStateChangedListener } from "../utils/firebase/firebase.utils";
export const UserContext = createContext({
currentUser: null,
setCurrentUser: () => null,
});
export const UserProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(null);
const value = { currentUser, setCurrentUser };
useEffect(() => {
const unsubscribe = onAuthStateChangedListener((user) => {
console.log(user);
setCurrentUser(user);
});
return unsubscribe;
}, []);
return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
};
應用程序.js:
import { Routes, Route, Navigate } from "react-router-dom";
import Authentication from "./routes/authentication/authentication";
import ProtectedRoute from "./components/common/protected-route/protectedRoute";
import Playground from "./routes/playground/playground";
import PageNotFound from "./components/common/page-not-found/pageNotFound";
function App() {
return (
<div>
<Routes>
<Route path="/" exact element={<Navigate to="/auth" />} />
<Route element={<ProtectedRoute />}>
<Route path="/playground" element={<Playground />} />
</Route>
<Route path="/auth" element={<Authentication />} />
<Route path="/not-found" element={<PageNotFound />} />
<Route path="*" element={<Navigate to="/not-found" />} />
</Routes>
</div>
);
}
export default App;
我究竟做錯了什么? 任何幫助表示贊賞。 謝謝!
如果您想阻止您的登錄用戶進入登錄頁面,請在SignInForm
中添加一個檢查:
const { currentUser } = useContext(UserContext);
// If there is a user redirect to whatever page you want:
if (currentUser) return <Navigate to="/playground" />;
return <div>Actual login page content</div>
為了讓您的用戶在頁面刷新后保持登錄狀態,最簡單的方法是使用localStorge
,如下所示:
import { createContext, useEffect, useState } from "react";
import { onAuthStateChangedListener } from "../utils/firebase/firebase.utils";
export const UserContext = createContext({
currentUser: null,
setCurrentUser: () => null,
});
export const UserProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(
localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null
);
useEffect(() => {
const unsubscribe = onAuthStateChangedListener((user) => {
console.log(user);
localStorage.setItem(JSON.stringify(user));
setCurrentUser(user);
});
return unsubscribe;
}, []);
return (
<UserContext.Provider value={(currentUser, setCurrentUser)}>{children}</UserContext.Provider>
);
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.