[英]How to persist authentication in Next.js using firebase after token expiration and or refreshing the page
我正在使用 firebase 和 next.js 构建一个应用程序。 我在使用 firebase 的身份验证流程时遇到了困难。 一切都进展顺利,直到我注意到一个错误/错误。 如果我让我的计算机登录应用程序一段时间,并且每当我刷新页面时,似乎两者都会导致我被重定向回我的登录页面。 我可以理解为什么刷新会触发我的重定向,因为可能没有足够的时间来检查 onAuthStateChange 以让const { user } = useAuth()
运行,因为初始页面加载时没有用户(刷新后) .) 它将进入{ else }
导致我此时重定向。 但有趣的是,如果我只是单击我的仪表板(受保护的页面)链接,我仍然通过了身份验证。 没有重定向。 以下是我的身份验证组件的代码:
AuthComp.js:
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { useAuth } from "../../context/AuthContext";
function LoadingScreen() {
return <div className="fixed top-0 right-0 h-screen w-screen z-50 flex justify-center items-center">
<div className="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-gray-900"></div>
</div>
}
export function AuthComp(props) {
const [isAuthenticated, setIsAuthenticated] = useState(false)
const router = useRouter();
const { user } = useAuth();
useEffect(() => {
let out;
if (user) {
setIsAuthenticated(true)
return () => out ? out() : null
} else {
router.push('/auth')
}
return () => out;
}, [user])
if (!user && (!isAuthenticated)) {
return <LoadingScreen />;
}
return <props.Component user={user} />
};
这是我的身份验证上下文文件的代码:AuthContext.js:
import React, { useState, useEffect, createContext, useContext } from 'react'
import { fbase } from '../utils/auth/firebaseClient'
export const AuthContext = createContext()
export default function AuthProvider({ children }) {
const [user, setUser] = useState(null)
const [loadingUser, setLoadingUser] = useState(true) // Helpful, to update the UI accordingly.
useEffect(() => {
// Listen authenticated user
const unsubscriber = fbase.auth.onAuthStateChanged(async (user) => {
try {
if (user) {
setUser(user);
} else {
setUser(null)
return;
}
} catch (error) {
// Most probably a connection error. Handle appropriately.
console.log('an error occurred', error);
} finally {
setLoadingUser(false)
}
})
// Unsubscribe auth listener on unmount
return () => unsubscriber()
}, [])
return (
<AuthContext.Provider value={{ user, setUser, loadingUser }}>
{children}
</AuthContext.Provider>
)
}
// Custom hook that shorthands the context!
export const useAuth = () => useContext(AuthContext)
可能没有足够的时间及时检查 onAuthStateChange
onAuthStateChanged
的第一个用户结果绝对不能保证立即发生。 您应该期望第一个回调需要一些时间,因为首先加载用户的持久令牌然后进行验证。
在第一次触发回调之前,您应该假设用户处于“未知”状态。 在第一次回调之前,用户既没有登录也没有注销。 我建议在编写您的应用程序时考虑到这种三元状态。 (相关, firebase.auth().currentUser
在页面首次加载时将始终为 null。)要了解有关此行为的更多信息,我建议阅读此博客文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.