使用Firebase自动注销用户

时间:2019-11-17 09:31:54

标签: javascript reactjs firebase google-cloud-firestore firebase-authentication

我希望我的reactjs应用程序中的用户 1小时后自动注销。 (登录会话应为1小时,然后用户需要再次登录。)

我不知道该怎么做。当前,用户可以使用Firebase函数' .signInWithEmailAndPassword(email,password)'登录,但是随后必须手动单击注销按钮(触发Firebase'。 signOut( )'函数)。另外,这是当用户登录时(当然在注销后会删除)时将存储在我的浏览器本地存储中的数据:

enter image description here

withAuthentication.js代码

import React from 'react'
import { connect } from 'react-redux';
import { compose } from 'recompose';
import { withFirebase } from '../Firebase';

const withAuthentication = (Component) => {
  class WithAuthentication extends React.Component {

    constructor(props) {
        super(props);

        this.props.onSetAuthUser(JSON.parse(localStorage.getItem('authUserLocalStorage')));
    }

    componentDidMount() {
        this.listener = this.props.firebase.onAuthUserListener(
            //next
            authUser => {
                localStorage.setItem('authUserLocalStorage', JSON.stringify(authUser));
                this.props.onSetAuthUser(authUser)
            },
            //fallback
            () => {
                localStorage.removeItem('authUserLocalStorage');
                this.props.onSetAuthUser(null)
            }
        );
    }

    componentWillUnmount() { 
        this.listener();
    }

    render() {
        return (
            <Component {...this.props} />
        );
    }
}

const mapDispatchToProps = dispatch => ({ //used for dispatching actions to the store (redux)
    onSetAuthUser: authUser =>
    dispatch({ type: 'AUTH_USER_SET', authUser }),
});

return compose(
    withFirebase,
    connect(null, mapDispatchToProps)
)(WithAuthentication);
};
export default withAuthentication;

Firebase.js代码

import firebaseApp from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/storage';

const firebaseConfig = {
 apiKey: process.env.REACT_APP_API_KEY,
 authDomain: process.env.REACT_APP_AUTH_DOMAIN,
 databaseURL: process.env.REACT_APP_DATABASE_URL,
 projectId: process.env.REACT_APP_PROJECT_ID,
 storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
 messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
 appId: process.env.REACT_APP_APP_ID,
};

class Firebase {
constructor() {
    firebaseApp.initializeApp(firebaseConfig); //initialize firebase with the configuration

    this.fieldValue = firebaseApp.firestore.FieldValue; //(using Cloud Firestore)

    //we implement the authentication & database API for our Firebase class
    this.firebaseAuth = firebaseApp.auth(); //instantiate the firebase auth package
    this.firestoreDb = firebaseApp.firestore(); //instantiate Cloud Firestore (using Cloud Firestore)
    this.storage = firebaseApp.storage(); //instantiate firebase storage
}

/*****************************************************************
 ********* Authentication API (authentication interface) *********
 ****************************************************************/

// sign up function (registration)
doCreateUserWithEmailAndPassword = (email, password) =>
    this.firebaseAuth.createUserWithEmailAndPassword(email, password); //call the Firebase 'createUserWithEmailAndPassword' to create a user

// login/sign-in function
doSignInWithEmailAndPassword = (email, password) =>
    this.firebaseAuth.signInWithEmailAndPassword(email, password);

// Sign out function (Firebase knows about the currently authenticated user. If no user is authenticated, nothing will happen when this function is called)
doSignOut = () => 
    this.firebaseAuth.signOut();

// Reset password for an authenticated user
doPasswordReset = (email) =>
    this.firebaseAuth.sendPasswordResetEmail(email);

// Change password for an authenticated user
doPasswordUpdate = password =>
    this.firebaseAuth.currentUser.updatePassword(password);


// send a verification email
doSendEmailVerification = () =>
    this.firebaseAuth.currentUser.sendEmailVerification({
        url: process.env.REACT_APP_CONFIRMATION_EMAIL_REDIRECT,
    });


/*****************************************************************
 ******************* User API (User interface) *******************
 ****************************************************************/

 //we create a function, that makes use of the firebase function 'onAuthStateChanged()', so we can call it from other components
onAuthUserListener = (next, fallback) =>

    this.firebaseAuth.onAuthStateChanged(authUser => {
        if (authUser) { //if user is not null

            this.user(authUser.uid)
            .get() //(using Cloud Firestore)
            .then(snapshot => {
                const dbUser = snapshot.data(); //(using Cloud Firestore)

                    //default empty roles
                    if (!dbUser.roles) {
                        dbUser.roles = {};
                    }

                    //merge auth and db user
                    //we merge everything from the database user with the unique identifier and email from the authenticated user
                    authUser = {
                        uid: authUser.uid,
                        email: authUser.email,

                        //To find out if a user has a verified email, you can retrieve this information from the authenticated user
                        emailVerified: authUser.emailVerified,
                        providerData: authUser.providerData,

                        ...dbUser
                    };

                    next(authUser); //implement the specific implementation details of every higher-order component (local state for authentication, redirect for authorization)
                });
        } else {
            fallback(); //implement the specific implementation details of every higher-order component (local state for authentication, redirect for authorization)
        }
    });
}
export default Firebase;

1 个答案:

答案 0 :(得分:1)

我也在这个问题上苦苦挣扎。不幸的是,使用Firebase Auth的默认实现,无法再更改刷新令牌的持续时间。

您可以通过使用一个小时的超时然后手动注销用户来解决此问题。

this.firebaseAuth.onAuthStateChanged((user) => {
    let userSessionTimeout = null;

    if (user === null && userSessionTimeout) {
      clearTimeout(userSessionTimeout);
      userSessionTimeout = null;
    } else {
      user.getIdTokenResult().then((idTokenResult) => {
        const authTime = idTokenResult.claims.auth_time * 1000;
        const sessionDurationInMilliseconds = 60 * 60 * 1000; // 60 min
        const expirationInMilliseconds = sessionDurationInMilliseconds - (Date.now() - authTime);
        userSessionTimeout = setTimeout(() => this.firebaseAuth.signOut(), expirationInMilliseconds);
      });
    }
  });