如何避免未登录用户查看已登录用户的页面?接下来的 JS 客户端身份验证



我正在使用localStorage在客户端处理我的应用程序的身份验证,如果localStorage中没有"用户"项,则表示该人未登录,应重定向到/login页面。

问题是,例如,当有人第一次访问根页面并且没有登录时,该人将能够看到 1 或 2 秒的"/"主页内容,这应该只有登录用户才能看到,然后,用户将被重定向到"/login"进行身份验证。

我知道为什么会发生这种情况,但我想知道是否有更好的方法来做到这一点并避免这个烦人的小问题。

这是我login.js页面代码:

import React from "react";
import Image from "next/image";
import GoogleLogin from "react-google-login";
import { FcGoogle } from "react-icons/fc";
import { useRouter } from "next/router";
import axios from "axios";
const Login = () => {
const router = useRouter();
const apiUserLogin = async (userName, userId, userImage) => {
try {
axios.post(
`/api/users/login?name=${userName}&googleId=${userId}&imageUrl=${userImage}`
);
} catch (error) {
console.log(error);
}
};
const responseGoogle = (response) => {
localStorage.setItem("user", JSON.stringify(response.profileObj));
const { name, googleId, imageUrl } = response.profileObj;
apiUserLogin(name, googleId, imageUrl).then(() => {
router.push("/");
});
};
return (
<div className="flex flex-col items-center justify-center h-screen bg-black">
<video
src="/PostItvideo2.mp4"
type="video/mp4"
loop
controls={false}
muted
autoPlay
className="object-cover w-full h-full brightness-50"
/>
<div className="absolute top-0 bottom-0 left-0 right-0 flex flex-col items-center justify-center">
<div className="p-3">
<Image
src="/Postit-logofull.svg"
width={140}
height={80}
alt="logo"
/>
</div>
<GoogleLogin
clientId={`${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}`}
render={(renderProps) => (
<button
type="button"
className="flex items-center justify-center px-8 py-3 text-lg font-bold text-black bg-white border-none rounded-lg outline-none cursor-pointer"
onClick={renderProps.onClick}
>
<FcGoogle size={21} className="mr-2" /> Sign in with Google
</button>
)}
onSuccess={responseGoogle}
onFailure={responseGoogle}
cookiePolicy="single_host_origin"
/>
</div>
</div>
);
};
export default Login; 

这是我_app.js代码,这是"如果未登录则重定向"发生的地方:

import React, { useEffect } from "react";
import { AppContext } from "../context/context";
import { useRouter } from "next/router";
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
const router = useRouter();
useEffect(() => {
const userInfo =
localStorage.getItem("user") !== "undefined"
? JSON.parse(localStorage.getItem("user"))
: null;
if (router.pathname !== "/login" && !userInfo) router.push("/login");
}, []);
return (
<AppContext>
<Component {...pageProps} />
</AppContext>
);
}
export default MyApp;

通常会有一个加载屏幕。

function MyApp({ Component, pageProps }) {
const router = useRouter();
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const userInfo = GET_USER_FROM_LS;
if (router.pathname !== "/login" && !userInfo) {
router.push("/login");
} else {
setIsLoading(false)
}
}, []);
if(isLoading) {
return <YourLoadingComponent />
}
return YOUR_DEFAULT_RETURN;
}

我个人尽量保持_app干净,所以我可能会将所有登录逻辑放在AppContext中。

最新更新