Firebase身份验证延迟刷新 [英] firebase auth delayed on refresh
问题描述
我的反应路线利用 onEnter
函数来判断用户是否被认证。例如
< Route path =/ securecomponent = {Dashboard} onEnter = {requireAuth} />
另外,我的 requireAuth
函数看起来像这样:
$ p $ function(nextState,replace){
console.log('requireAuth',firebase.auth()。当前用户);
if(!firebase.auth()。currentUser){
console.log('尝试访问安全路由,请先登录。
replace({
pathname:'/ login',
state:{nextPathname:nextState.location.pathname}
});
}
};
然而,在硬刷新上, firebase.auth稍有延迟().currentUser
。它首先是空的,然后执行 POST
到firebase服务器以确定auth状态。当它返回 currentUser
对象被填充。这个延迟会导致问题。
我的hacky解决方案如下: update:这实际上不工作...
function(nextState,replace){
setTimeout(function(){
console.log('requireAuth',firebase.auth()。currentUser );
if(!firebase.auth()。currentUser){
console.log('试图访问一个安全的路由,请先登录');
replace({
pathname:'/ login',
state:{nextPathname:nextState.location.pathname}
});
}
},50);
};
只需在超时时间内包装即可。然而,我真的不喜欢这个...任何想法?
$ b $ p 更新:
我还试图将它封装在 onAuthStateChanged
侦听器中,它应该比 setTimeout
并有明确的时间延迟。代码如下:
function(nextState,replace){
var unsubscribe = firebase.auth()。onAuthStateChanged功能(用户){
if(!user){
console.log('尝试访问安全路由');
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()。 );
//替换({
//路径名:'/ login',
// state:{nextPathname:nextState.location.pathname}
//});
//}
//},50);
};
执行两个日志语句,但react-router replace
似乎没有被正确执行。也许对于反应路由专家来说,这是一个不同的问题。
更新2:
<当我正在做这件事的时候,已经是深夜了。显然 setTimeout
实际上并不工作。
好的。因此,我可以通过使用firebase提供的 localStorage
变量来解决这个问题,以存储用户信息。
$ p $ function(nextState,replace){
if(!firebase.auth()。currentUser){
让hasLocalStorageUser = false;
for(let key in localStorage){
if(key.startsWith(firebase:authUser:)){
hasLocalStorageUser = true;
if(!hasLocalStorageUser){
console.log('尝试访问安全路由,请先认证');
replace({
pathname:'/ login',
state:{nextPathname:nextState.location.pathname}
});
}
}
};
Hard refreshes on my SPA React/Firebase application does not maintain auth state on immediate execution of a function. I have a workaround, but it's sketchy.
My react routes utilize the onEnter
function to determine whether or not the user is authenticated or not. For instance
<Route path="/secure" component={Dashboard} onEnter={requireAuth}/>
Furthermore, my requireAuth
function looks like this:
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 }
});
}
};
However, on a hard refresh there is a slight delay on firebase.auth().currentUser
. It's null at first, then executes a POST
to firebase servers in order to determine auth state. When it returns the currentUser
object is populated. This delay causes issues though.
My hacky solution is the following: update: this doesn't actually work...
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);
};
Simply wrap it in a timeout. However, I really don't like this... any thoughts?
Update:
I have also tried to wrap it within a onAuthStateChanged
listener, which should be more accurate than a setTimeout
with a definitive time delay. Code as follows:
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);
};
The two log statements are executed, but react-router replace
does not seem to be executed correctly. Perhaps that's a different question for the react-router experts.
update 2:
It was late at night when I was working on this. Apparently setTimeout
doesn't actually work either.
Okay. So, I was able to solve this by utilizing the localStorage
variable that firebase provides to store the user information.
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 }
});
}
}
};
这篇关于Firebase身份验证延迟刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!