Reactjs 如何使用Firebase刷新令牌来持久化身份验证?
几周来我一直在试图弄明白这一点,但要么是看不懂文档,要么是别的什么。我很感激你能给我的任何帮助 我正在使用Firebase SDK 我有我的服务器端路由,在其中我可以访问令牌并将其发送到前端:Reactjs 如何使用Firebase刷新令牌来持久化身份验证?,reactjs,firebase,authentication,firebase-authentication,refresh-token,Reactjs,Firebase,Authentication,Firebase Authentication,Refresh Token,几周来我一直在试图弄明白这一点,但要么是看不懂文档,要么是别的什么。我很感激你能给我的任何帮助 我正在使用Firebase SDK 我有我的服务器端路由,在其中我可以访问令牌并将其发送到前端: const admin = require("firebase-admin") admin.initializeApp() exports.loginRoute = (req, res) => { const user = { email: req.bo
const admin = require("firebase-admin")
admin.initializeApp()
exports.loginRoute = (req, res) => {
const user = {
email: req.body.email,
password: req.body.password
}
const { valid, errors } = validateLoginData(user)
if (!valid) {
return res.status(400).json(errors)
}
admin
.auth()
.signInWithEmailAndPassword(user.email, user.password)
.then((data) => {
console.log(data.user.refreshToken, "refresh token")
return data.user.getIdToken(true)
})
.then((token) => {
return res.json({ token })
})
.catch((err) => {
console.error(err)
if (err.code === "auth/user-not-found") {
return res.status(400).json({ general: "User not found" })
} else if (err.code === "auth/wrong-password") {
return res
.status(400)
.json({ password: "User credentials don't match" })
} else {
res.status(500).json({
error: "Something went wrong, please try again."
})
}
})
}
在这里,我可以使用刷新令牌(在前端)来获取新的身份验证令牌,但我不知道如何创建路由来实现这一点:
if (token) {
const decodedToken = jwtDecode(token)
if (decodedToken.exp * 1000 < Date.now()) {
localStorage.setItem("Authentication", false)
//axios request to persist authentication would go here
}
}
观察员(客户端):
如果在客户端代码中使用Firebase身份验证JavaScript SDK登录,则它已保持用户的登录状态,并在重新加载页面时尝试恢复该状态。你自己不应该为此做任何事情 不过,您似乎在服务器端环境中使用了相同的SDK,这是非常不寻常的。如果您希望自己在服务器端环境中铸造代币,那么应该使用Firebase Admin SDK来实现。然后,您可以将该令牌发送回客户端,并使用它登录到Firebase身份验证
但对于绝大多数用例,我建议在客户端代码中使用Firebase身份验证SDK,以便SDK为您管理令牌的刷新。如果随后要将令牌传递给服务器,可以像现在一样使用
getIdToken()
。您还可以,或者更常见的是,监视是否恢复了用户的登录会话,如上文档的第一个示例所示。Firebase Authentication JavaScript SDK已保持用户的登录状态,并在重新加载页面时尝试恢复该状态。你自己不应该为此做任何事情。这对你不起作用吗?@FrankvanPuffelen它不起作用,我的令牌在1小时后过期,然后我必须注销并重新登录。所有内置提供程序的ID令牌在1小时后过期,这是有意义的。但是SDK会在这之前自动刷新令牌,因此您应该能够始终获得有效的令牌:您是否有可能将此令牌缓存在某个地方?嘿,Nathan。我试图在下面的回答中捕捉评论线索。如果这很有用,请单击向上投票按钮(▲) 如果它回答了您的问题,请单击复选标记(✓) 接受它。这样别人就知道你已经得到了(足够的)帮助。另请看@FrankvanPuffelen thank you,仍然习惯于堆叠。我感谢你的帮助和指导。
const login = async (credentials) => {
let token
await axios
.post("/api/login", credentials)
.then((res) => {
token = res.data.token
const FBIdToken = `Bearer ${token}`
localStorage.setItem("token", token)
localStorage.setItem("FBIdToken", FBIdToken)
localStorage.setItem("Authentication", true)
context.setAuthenticated((prev) => true)
})
.then(() => {
context.getUserData()
})
.then(() => {
context.setUserState((prevUserState) => ({
...prevUserState,
token
}))
})
.catch((err) => {
context.setUserErrors((prev) => ({
...prev,
errors: err.response.data
}))
})
history.push("/")
}
firebase.auth().onAuthStateChanged((user) => {
if (user) {
firebase
.auth()
.currentUser.getIdToken(/* forceRefresh */ true)
.then((idToken) => {
const FBIdToken = `Bearer ${idToken}`
localStorage.setItem("FBIdToken", FBIdToken)
})
.catch((err) => {
console.log(err)
})
} else {
localStorage.removeItem("FBIdToken")
}
})