小编典典

Firebase身份验证在刷新时延迟

reactjs

我的SPA React / Firebase应用程序上的硬刷新在立即执行功能时不保持身份验证状态。我有一个解决方法,但是它很粗略。

我的反应路线利用该onEnter功能来确定用户是否已通过身份验证。例如

<Route path="/secure" component={Dashboard} onEnter={requireAuth}/>

此外,我的requireAuth函数如下所示:

function (nextState, replace) {
        console.log('requireAuth', firebase.auth().currentUser);
        if (!firebase.auth().currentUser) {
            console.log('attempting to access a secure route. please login first.');
            replace({
                pathname: '/login',
                state: { nextPathname: nextState.location.pathname }
            });
        }
};

但是,在进行强制刷新时,会稍有延迟firebase.auth().currentUser。首先为null,然后POST对firebase服务器执行,以确定身份验证状态。返回时将currentUser填充对象。但是,这种延迟会导致问题。

我的hacky解决方案如下: 更新: 这实际上不起作用…

function (nextState, replace) {
    setTimeout(function () {
        console.log('requireAuth', firebase.auth().currentUser);
        if (!firebase.auth().currentUser) {
            console.log('attempting to access a secure route. please login first.');
            replace({
                pathname: '/login',
                state: { nextPathname: nextState.location.pathname }
            });
        }
    }, 50);
};

只需将其包装在超时中即可。但是,我真的不喜欢这个……有什么想法吗?

更新:

我还尝试将其包装在一个onAuthStateChanged侦听器中,这应该比setTimeout具有确定的时间延迟的a 更准确。代码如下:

function (nextState, replace) {
    var unsubscribe = firebase.auth().onAuthStateChanged(function (user) {
        if (!user) {
            console.log('attempting to access a secure route');
            replace({
                pathname: '/login',
                state: { nextPathname: nextState.location.pathname }
            })
            console.log('should have called replace');
        }
        unsubscribe();
    });
    // setTimeout(function () {
    //     console.log('requireAuth', firebase.auth().currentUser);
    //     if (!firebase.auth().currentUser) {
    //         console.log('attempting to access a secure route. please login first.');
    //         replace({
    //             pathname: '/login',
    //             state: { nextPathname: nextState.location.pathname }
    //         });
    //     }
    // }, 50);
};

这两个日志语句已执行,但是react-router replace似乎未正确执行。对于反应路由器专家来说,也许这是一个不同的问题。

更新2:

我正在做这件事的时候已经很晚了。显然setTimeout实际上也不起作用。


阅读 269

收藏
2020-07-22

共1个答案

小编典典

好的。因此,我能够利用localStoragefirebase提供的变量来存储用户信息来解决此问题。

function (nextState, replace) {
    if (!firebase.auth().currentUser) {
        let hasLocalStorageUser = false;
        for (let key in localStorage) {
            if (key.startsWith("firebase:authUser:")) {
                hasLocalStorageUser = true;
            }
        }
        if (!hasLocalStorageUser) {
            console.log('Attempting to access a secure route. Please authenticate first.');
            replace({
                pathname: '/login',
                state: { nextPathname: nextState.location.pathname }
            });
        }
    }
};
2020-07-22