reactjs - 如何使用 Firebase 刷新令牌来保持身份验证?
问题描述
几周以来,我一直试图弄清楚这一点,但似乎无法理解文档,或者其他什么。感谢您提供的任何帮助。
我正在使用 Firebase SDK
我有我的服务器端路由,我可以在其中访问令牌并将其发送到前面:
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
}
}
有没有人有一条可行的路线,或建议做什么?
编辑
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")
}
})
解决方案
如果您在客户端代码中使用 Firebase 身份验证 JavaScript SDK 登录,它已经保留了用户的登录状态,并在您重新加载页面时尝试恢复它。你不应该为此做任何事情。
不过,您似乎在服务器端环境中使用了相同的 SDK,这很不寻常。如果您想在服务器端环境中自己铸造令牌,则应使用 Firebase Admin SDK 来执行此操作。然后,您可以将该令牌发送回客户端,并使用它在那里登录 Firebase 身份验证。
但对于绝大多数用例,我建议在您的客户端代码中使用 Firebase 身份验证 SDK,以便 SDK 为您管理令牌的刷新。如果您想将令牌传递给服务器,您可以getIdToken()
像现在一样使用。您还可以监控 ID 令牌生成,或者更常见的是监控用户的登录会话是否已恢复,如有关检测当前用户的文档的第一个示例所示。
推荐阅读
- azure - 使用哪一个?microsoft/azure-cli 与 mcr.microsoft.com/azure-cli
- c++ - 对已定义的接口析构函数的未定义引用
- java - 如何测试@Scheduled 注释方法
- deployment - 在本地网络上提供 PWA 而不显示或禁用不安全的连接警告?
- python - 提高数据帧移位效率
- java - 次要和主要 GC 周期
- c# - 如何从文件中解析日期并添加时区信息
- apache-spark - gcloud dataproc 作业提交 spark 以 root 用户身份提交作业
- r - 如何使 for 循环可选
- elasticsearch - 在单个搜索查询中获取令牌位置 ElasticSearch v7.3