我一直在学习关于设置 NextJS、firebase 和 react-context 来处理用户身份验证的非常不错的教程。一切都很顺利,直到……我的 getServerSideProps
中的代码无法找到 cookie 'token',这导致我的 firebase 查询失败,触发我重定向到登录页面。
所以,简而言之,我可以登录/注销用户并设置 cookie 令牌。但是,当我转到 SSR 检查令牌的页面时,它没有找到任何内容,而是触发了我的重定向。
我正在使用的 SSR + cookie 资源:https://colinhacks.com/essays/nextjs-firebase-authentication
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
try {
const cookies = nookies.get(ctx);
console.log("cookies token", cookies.token); // returns empty string :(
const token = await firebaseAdmin.auth().verifyIdToken(cookies.token);
// * the user is authenticated
const { uid, email } = token;
// ! stuff would be fetched here
} catch (error) {
// either the `token` cookie doesn't exist
// or the token verification failed
// either way: redirect to login page
return {
redirect: {
permanent: false,
destination: "/auth/login",
},
props: {} as never,
};
}
return {
props: { data, params: ctx.params },
};
};
export const AuthContext = createContext<{ user: firebase.User | null }>({
user: null,
});
export function AuthProvider({ children }: any) {
const [user, setUser] = useState<firebase.User | null>(null);
useEffect(() => {
if (typeof window !== "undefined") {
(window as any).nookies = nookies;
}
return firebaseAuth.onIdTokenChanged(async (user) => {
console.log(`token changed!`);
if (!user) {
console.log(`no token found...`);
setUser(null);
nookies.destroy(null, "token");
nookies.set(null, "token", "", {});
return;
}
console.log(`updating token...`);
const token = await user.getIdToken();
// console.log("got user token:", token);
// console.log("got user:", user);
setUser(user);
nookies.destroy(null, "token");
nookies.set(null, "token", token, {});
});
}, []);
// force token refresh every 10 minutes
useEffect(() => {
const handle = setInterval(async () => {
const user = firebaseAuth.currentUser;
if (user) await user.getIdToken(true);
}, 10 * 60 * 1000);
// clean up
return () => clearInterval(handle);
}, []);
return (
<AuthContext.Provider value={{ user }}>{children}</AuthContext.Provider>
);
}