Firebase:如果currentUser为null,如何在http请求上刷新idToken



我目前正在使用React JS和Firebase来处理登录操作。

我和团队决定使用自定义身份验证系统的方式进行登录。因此,我们从后端生成一个自定义令牌,然后前端通过signInWithCustomToken执行登录。

在这里之前,一切都像一个魅力,但一旦我登录,如果我刷新页面,currentUser对象就会变为null,所以我不可能在上面调用方法getIdToken(true(来刷新令牌。每次我使用axios发出http请求时,都会调用firebase.auth((.currentUser.getIdToken(true(方法(使用拦截器将Authorization字段添加到请求中(。如果我登录并在不重新加载的情况下发出http请求,它可以正常工作,但如果我刷新,我会收到一个错误,因为currentUser对象丢失了内容并变为null。

我花了大约8个小时在网上冲浪寻找解决方案。我已经看到有人说,解决方案是将用户带到onAuthStateChanged观察器中,但问题是,当我发出http请求时,我无法输入观察器来获取用户的值,因为观测者不是我需要时可以调用的函数

此外,我还试图将onAuthStateChanged观察器在触发(登录或注销期间(时返回的用户对象保存在localStorage上,但它与返回的对象不同,并且在proto中没有getIdToken函数。所以对我来说没用。

我还尝试使用firebase.auth((.setPersistence(firebase.aauth.auth.Persistence.SESSION(,将onAuthStateChanged观察器返回的用户对象传递给它,但没有任何更改。

这是我的项目代码:

******AXIOS请求拦截器******

instanceAXIOS.interceptors.request.use(
async config => {
const { refreshedToken } = await refreshUserTokenTEST()
config.headers.Authorization = `Bearer ${ refreshedToken }`
return config
},
error => Promise.reject(error)
)

******刷新令牌******

const refreshUserTokenTEST = () => {
try {
return firebase
.auth()
.currentUser
.getIdToken(true)
.then(token => {
return { status: 200, refreshedToken: token }
})
.catch(err => {
console.error(err)
return { status: 500, refreshedToken: null }
})
} catch (exc) {
console.error("ERROR DURING TOKEN REFRESH")
return { status: 404, refreshedToken: null }
}
}

******firebasePersistenceOption函数******

const firebasePersistenceOption = async (userObject) => {
return firebase
.auth()
.setPersistence(firebase.auth.Auth.Persistence.SESSION)
.then(function() {
return userObject
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
})
}

******onAuthStateChanged OBSERVER******

firebase.auth().onAuthStateChanged(async function(user) {
if (user) {
console.log("LOGGED IN")
await firebasePersistenceOption(user)
} else {
console.log("LOGGED OUT")
}
})

就像我说的,在不重新加载页面的情况下,一切都很好,所以代码中没有错误(我几乎希望是这样(。

我终于找到了这个问题的解决方案。由于@DougStevenson的建议和GitHub上的讨论,我能够编写一个函数来获取刷新的id令牌。

这是基本代码:

// get the current user inside the observer
// then refresh the token
// and finally unsubscribe the observer
const getIdTokenRefreshed = async () => {
return new Promise(async (resolve, reject) => {
const unsubscribe = firebase
.auth
.onAuthStateChanged(user => {
unsubscribe()
const refreshedToken = await user
.getIdToken(true)
.catch(err => console.error(err))
resolve(refreshedToken)
}, reject)
})
}

最新更新