Web firebase 保持用户登录
Web firebase keep user signed in
我正在为我的网络应用程序使用 firebase 身份验证。似乎在用户登录后,他们的会话只持续了大约一个小时,然后在他们返回网站或重新加载页面后,他们将被注销并需要重新登录。他们不是手动注销,而是在一段时间后被注销。 有没有办法让用户无限期地保持登录状态,直到他们要求退出?
代码如下:
/********************************************************************************
*** Description: A hook which listens for Firebase changes.
***
*** https://blog.logrocket.com/implementing-authentication-in-next-js-with-firebase/
********************************************************************************/
//==============================================================================
// IMPORTS
//==============================================================================
/* Yarn */
import { useState, useEffect } from 'react';
import {
getAuth,
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
sendPasswordResetEmail,
updateProfile
} from "firebase/auth";
import type { User } from "firebase/auth";
/* Personal */
import Firebase from '.';
//==============================================================================
// HELPER FUNCTIONS
//==============================================================================
/**
* Returns necessary information from a firebase user.
*
* @param user Firebase User.
* @returns An object containing the user's uid, email, and displayName.
*/
const formatAuthUser = (user: User) => ({
uid: user.uid,
email: user.email,
displayName: user.displayName
});
//==============================================================================
// EXPORTS
//==============================================================================
export default function useFirebaseAuth() {
const [authUser, setAuthUser] = useState(null);
const [loading, setLoading] = useState(true);
/**
* Callback function when authentication state changes.
*
* @param authState User's state.
* @returns
*/
const authStateChanged = async (authState: User) => {
if (!authState) {
setAuthUser(null);
setLoading(false);
return;
}
setLoading(true);
const formattedUser = formatAuthUser(authState);
setAuthUser(formattedUser);
setLoading(false);
};
/**
* Clear user.
*/
const clear = () => {
setAuthUser(null);
setLoading(true);
};
/**
* Sign in with email and password.
*
* @param email User's email.
* @param password User's password.
* @returns Promise of the UserCredentials.
*/
const signInWithEmailAndPasswordWrapper = (email: string, password: string) =>
signInWithEmailAndPassword(getAuth(Firebase), email, password);
/**
* Create a new account.
*
* @param email User's email.
* @param password User's password
* @returns Promise of the UserCredentials.
*/
const createUserWithEmailAndPasswordWrapper = (email: string, password: string) =>
createUserWithEmailAndPassword(getAuth(Firebase), email, password);
/**
* Updates a user's display name.
*
* @param displayName Unique username.
* @returns
*/
const updateUserDisplayName = (displayName: string) => {
setLoading(true);
const currentUser = getAuth(Firebase).currentUser;
updateProfile(currentUser, { displayName });
const formattedUser = {
uid: currentUser.uid,
email: currentUser.email,
displayName
};
setAuthUser(formattedUser);
setLoading(false);
}
/**
* Sends a password reset email.
*
* @param email Email to send password reset to.
* @returns
*/
const sendPasswordResetEmailWrapper = (email: string) =>
sendPasswordResetEmail(getAuth(Firebase), email)
/**
* Remove authentication.
*
* @returns
*/
const signOut = () => getAuth(Firebase).signOut().then(clear);
// Listen for Firebase state change.
useEffect(() => {
const unsubscribe = getAuth(Firebase).onAuthStateChanged(authStateChanged);
return () => unsubscribe();
}, []);
return {
authUser,
loading,
signInWithEmailAndPasswordWrapper,
createUserWithEmailAndPasswordWrapper,
updateUserDisplayName,
sendPasswordResetEmailWrapper,
signOut
};
}
这在上下文中用于访问应用程序中任何位置的身份验证状态:
/********************************************************************************
*** Description: Creates a wrapper to access auth variables in any component.
***
*** https://blog.logrocket.com/implementing-authentication-in-next-js-with-firebase/
********************************************************************************/
//==============================================================================
// IMPORTS
//==============================================================================
/* Yarn */
import { createContext, useContext } from 'react'
/* Personal */
import useFirebaseAuth from './useFirebaseAuth';
//==============================================================================
// CREATE CONTEXT
//==============================================================================
const authUserContext = createContext({
authUser: null,
loading: true,
signInWithEmailAndPasswordWrapper: (email: string, password: string) => null,
createUserWithEmailAndPasswordWrapper: (email: string, password: string) => null,
updateUserDisplayName: (displayName: string) => null,
sendPasswordResetEmailWrapper: (email: string) => null,
signOut: () => null
});
//==============================================================================
// EXPORTS
//==============================================================================
export function AuthUserProvider({ children }) {
const auth = useFirebaseAuth();
return <authUserContext.Provider value={auth}>{children}</authUserContext.Provider>;
}
/**
* Custom hook to use the authUserContext.
*/
export const useAuth = () => useContext(authUserContext);
整个应用程序都包含在 AuthUserProvider 中。
您需要启用令牌服务 API 和身份工具包 API 才能保持用户的登录状态。 我最初只有身份Toolkit API,因此当每小时请求一个新令牌时,它会失败,然后用户将被注销。
我正在为我的网络应用程序使用 firebase 身份验证。似乎在用户登录后,他们的会话只持续了大约一个小时,然后在他们返回网站或重新加载页面后,他们将被注销并需要重新登录。他们不是手动注销,而是在一段时间后被注销。 有没有办法让用户无限期地保持登录状态,直到他们要求退出?
代码如下:
/********************************************************************************
*** Description: A hook which listens for Firebase changes.
***
*** https://blog.logrocket.com/implementing-authentication-in-next-js-with-firebase/
********************************************************************************/
//==============================================================================
// IMPORTS
//==============================================================================
/* Yarn */
import { useState, useEffect } from 'react';
import {
getAuth,
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
sendPasswordResetEmail,
updateProfile
} from "firebase/auth";
import type { User } from "firebase/auth";
/* Personal */
import Firebase from '.';
//==============================================================================
// HELPER FUNCTIONS
//==============================================================================
/**
* Returns necessary information from a firebase user.
*
* @param user Firebase User.
* @returns An object containing the user's uid, email, and displayName.
*/
const formatAuthUser = (user: User) => ({
uid: user.uid,
email: user.email,
displayName: user.displayName
});
//==============================================================================
// EXPORTS
//==============================================================================
export default function useFirebaseAuth() {
const [authUser, setAuthUser] = useState(null);
const [loading, setLoading] = useState(true);
/**
* Callback function when authentication state changes.
*
* @param authState User's state.
* @returns
*/
const authStateChanged = async (authState: User) => {
if (!authState) {
setAuthUser(null);
setLoading(false);
return;
}
setLoading(true);
const formattedUser = formatAuthUser(authState);
setAuthUser(formattedUser);
setLoading(false);
};
/**
* Clear user.
*/
const clear = () => {
setAuthUser(null);
setLoading(true);
};
/**
* Sign in with email and password.
*
* @param email User's email.
* @param password User's password.
* @returns Promise of the UserCredentials.
*/
const signInWithEmailAndPasswordWrapper = (email: string, password: string) =>
signInWithEmailAndPassword(getAuth(Firebase), email, password);
/**
* Create a new account.
*
* @param email User's email.
* @param password User's password
* @returns Promise of the UserCredentials.
*/
const createUserWithEmailAndPasswordWrapper = (email: string, password: string) =>
createUserWithEmailAndPassword(getAuth(Firebase), email, password);
/**
* Updates a user's display name.
*
* @param displayName Unique username.
* @returns
*/
const updateUserDisplayName = (displayName: string) => {
setLoading(true);
const currentUser = getAuth(Firebase).currentUser;
updateProfile(currentUser, { displayName });
const formattedUser = {
uid: currentUser.uid,
email: currentUser.email,
displayName
};
setAuthUser(formattedUser);
setLoading(false);
}
/**
* Sends a password reset email.
*
* @param email Email to send password reset to.
* @returns
*/
const sendPasswordResetEmailWrapper = (email: string) =>
sendPasswordResetEmail(getAuth(Firebase), email)
/**
* Remove authentication.
*
* @returns
*/
const signOut = () => getAuth(Firebase).signOut().then(clear);
// Listen for Firebase state change.
useEffect(() => {
const unsubscribe = getAuth(Firebase).onAuthStateChanged(authStateChanged);
return () => unsubscribe();
}, []);
return {
authUser,
loading,
signInWithEmailAndPasswordWrapper,
createUserWithEmailAndPasswordWrapper,
updateUserDisplayName,
sendPasswordResetEmailWrapper,
signOut
};
}
这在上下文中用于访问应用程序中任何位置的身份验证状态:
/********************************************************************************
*** Description: Creates a wrapper to access auth variables in any component.
***
*** https://blog.logrocket.com/implementing-authentication-in-next-js-with-firebase/
********************************************************************************/
//==============================================================================
// IMPORTS
//==============================================================================
/* Yarn */
import { createContext, useContext } from 'react'
/* Personal */
import useFirebaseAuth from './useFirebaseAuth';
//==============================================================================
// CREATE CONTEXT
//==============================================================================
const authUserContext = createContext({
authUser: null,
loading: true,
signInWithEmailAndPasswordWrapper: (email: string, password: string) => null,
createUserWithEmailAndPasswordWrapper: (email: string, password: string) => null,
updateUserDisplayName: (displayName: string) => null,
sendPasswordResetEmailWrapper: (email: string) => null,
signOut: () => null
});
//==============================================================================
// EXPORTS
//==============================================================================
export function AuthUserProvider({ children }) {
const auth = useFirebaseAuth();
return <authUserContext.Provider value={auth}>{children}</authUserContext.Provider>;
}
/**
* Custom hook to use the authUserContext.
*/
export const useAuth = () => useContext(authUserContext);
整个应用程序都包含在 AuthUserProvider 中。
您需要启用令牌服务 API 和身份工具包 API 才能保持用户的登录状态。 我最初只有身份Toolkit API,因此当每小时请求一个新令牌时,它会失败,然后用户将被注销。