繁体   English   中英

Web firebase 保持用户登录

[英]Web firebase keep user signed in

我正在为我的 web 应用程序使用 firebase 身份验证。 好像用户登录后,他们的 session 只持续了一个小时左右,然后在他们回到网站或重新加载页面后,他们将被注销,需要重新登录。 他们不是手动退出,而是在一段时间后退出。 有没有办法让用户无限期地登录,直到他们要求退出?

这是代码:

/********************************************************************************
 *** 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
    };
}

这在上下文中用于访问应用程序中任何位置的 auth state:

/********************************************************************************
 *** 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 以保持用户的登录状态。 我最初只有身份工具包 API,所以当每小时请求一个新令牌时,它会失败,然后用户将被注销。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM