我的SPA React / Firebase应用程序上的硬刷新在立即执行功能时不保持身份验证状态。我有一个解决方法,但是它很粗略。
我的反应路线利用该onEnter功能来确定用户是否已通过身份验证。例如
onEnter
<Route path="/secure" component={Dashboard} onEnter={requireAuth}/>
此外,我的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填充对象。但是,这种延迟会导致问题。
firebase.auth().currentUser
POST
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 更准确。代码如下:
onAuthStateChanged
setTimeout
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似乎未正确执行。对于反应路由器专家来说,也许这是一个不同的问题。
replace
更新2:
我正在做这件事的时候已经很晚了。显然setTimeout实际上也不起作用。
好的。因此,我能够利用localStoragefirebase提供的变量来存储用户信息来解决此问题。
localStorage
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 } }); } } };