#javascript #reactjs #authentication #next.js
Вопрос:
Я настроил аутентификацию пользователя, при которой, если пользователь вошел в систему, отображается определенная страница, но если нет, отображается заставка.
Так же, как и для localhost:3000/
(домашняя страница, должна показывать заставку или панель мониторинга вошедшего в систему пользователя)
Как я могу гарантировать, что он должен показывать только правильную страницу, не мигая заставкой?
Компонент «Главная страница» (или панель мониторинга)
const Home = () => {
const { user } = useUser();
const MainComponent = () => {
return (
<>
<SidebarNav />
<main className="flex-1 bg-gray-100">
code goes here
</main>
</>
);
};
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
{user ? (
<div>{MainComponent()}</div>
) : (
<SplashPage />
)}
</>
);
};
export default Home;
Моя авторизация пользователя:
const UserContext = createContext({});
export default function AuthContext({ children }) {
const router = useRouter();
const [user, setUser] = useState(null);
useEffect(() => {
checkUser();
}, []);
useEffect(() => {
Hub.listen("auth", () => {
// perform some action to update state whenever an auth event is detected
checkUser();
});
}, []);
const checkUser = async () => {
try {
// code to get user
} catch (err) {
// no current signed in user
console.log("error with AuthContext", err);
setUser(null);
}
};
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
);
}
export const useUser = () => useContext(UserContext);
и мой _app.js
function MyApp({ Component, pageProps }) {
const getLayout = Component.getLayout || ((page) => page);
return <AuthContext>{getLayout(<Component {...pageProps} />)}</AuthContext>;
}
export default MyApp;
Комментарии:
1. Поскольку вы выполняете проверку пользователя на стороне клиента, у вас всегда будет отображаться содержимое, которое было предварительно отрисовано на сервере (не прошедшее проверку подлинности), поэтому мигает заставка. Рассматривали ли вы возможность переноса чека на сервер вместо этого (если это вообще возможно)?
2. @juliomalves Так нравится, как
ServerSideProps
проверить пользователя? Могу ли я все еще написать это в AuthContext? Или это не работает с контекстом?
Ответ №1:
Я предлагаю поставить 3 статуса в ваш процесс аутентификации. загрузка, аутентификация и проверка подлинности. итак, недостающая часть-это загрузка.
Все, что вам нужно сделать сейчас, это изменить setUser(null) в CheckUser на {} или false. которые позволяют вам узнать, в каком статусе аутентификации вы находитесь
const checkUser = async () => {
try {
// code to get user
} catch (err) {
// no current signed in user
console.log("error with AuthContext", err);
setUser(false);
}
};
В компоненте панели мониторинга:
const Home = () => {
const { user } = useUser();
//loading state, show nothing
if(user===null) return null
if(user===false) return <SplashPage />
return <>
<SidebarNav />
<main className="flex-1 bg-gray-100">
code goes here
</main>
</>
export default Home;
Комментарии:
1. Как бы вы использовали аутентификацию на стороне сервера? вместо того, чтобы использовать ваше текущее решение? Или как насчет того, чтобы что-то сделать на моей контекстной странице?
2. @hellomello SSR в основном предназначен для SEO, и при активации вы отключаете статическую генерацию. для аутентификации требуется клиентский пользователь, у которого в любом случае есть файлы cookie/токен. Поэтому я рекомендую вместо этого обработать проверку подлинности клиента.