firebase - 如何在 React Native 上处理 Firebase 过期的身份验证令牌
问题描述
我在我的 react 本机应用程序中使用 firebase 作为后端。所有客户端 API 请求都转到我的 firebase 云函数,这些函数使用 Firebase 处理所有后端逻辑(身份验证、firestore、存储)。对于我的身份验证逻辑,一旦用户使用电子邮件和密码登录,我就会得到一个令牌。令牌存储在 AsyncStorage 中,并添加到后端的每个请求的标头中。
到目前为止一切正常,问题是令牌在 1 小时左右后过期,使用被迫再次登录。我搜索了 firebase 文档和网络,我知道我需要在每个经过身份验证的请求之前请求一个新令牌。问题是我不知道怎么做?
为了提高精度,我对所有需要身份验证的请求使用中间件函数 (isAuthenticated),我在其中验证令牌(这是在我的后端服务器中完成的)。
// Users routes
app.post("/signup", signup);
app.post("/login", login);
app.post("/user/image", isAuthenticated, uploadImage);
app.post("/user", isAuthenticated, addUserDetails);
我的问题是如何实现令牌刷新逻辑,我可以要求一个过期的新令牌吗?提前致谢。
更新:(更多详细信息)这是我首先获取令牌的方式:客户端应用程序(移动+网络)将 REST 请求发送到我的 firebase 函数。例如登录,我有这个功能:
exports.login = (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);
firebase
.auth()
.signInWithEmailAndPassword(user.email, user.password)
.then(data => {
return data.user.getIdToken();
})
.then(token => {
return res.json({ token });
})
.catch(err => {
return res
.status(403)
.json({ general: "Wrong credentials, please try again" });
});
};
登录后,客户端会收到令牌并使用 AsyncStorage/LocalStorage 将其存储,以便将其包含在授权标头中。
对于所有经过身份验证的根,我使用此中间件函数检查用户令牌:
exports.isAuthenticated = async (req, res, next) => {
let idToken;
if (
req.headers.authorization &&
req.headers.authorization.startsWith("Bearer ")
) {
idToken = req.headers.authorization.split("Bearer ")[1];
} else {
console.error("No token found");
return res.status(403).json({ error: "Unauthorized" });
}
admin
.auth()
.verifyIdToken(idToken)
.then(decodedToken => {
req.user = decodedToken;
return db
.collection("users")
.where("userId", "==", req.user.uid)
.limit(1)
.get();
})
.then(data => {
return next();
})
} catch (err) {
console.error(err);
}
};
提前致谢。
解决方案
我可以看到有一段时间没有人更新这个,所以我想我会写下我在后端所做的事情来重新验证过期的令牌。这被埋在某个地方,很难找到,因为官方文档没有涵盖这一点。
let body = {
grant_type: "refresh_token",
refresh_token: req.body.refreshToken || null
};
if (!body.refresh_token) {
return res.status(400).json({
message: ERROR._400
})
}
const {data: {refresh_token, id_token}} = await axios.post(`https://securetoken.googleapis.com/v1/tokenkey=${config.apiKey}`, body);
推荐阅读
- php - 要启用扩展,请验证它们是否已在您的 .ini 文件中启用,即使在所有扩展都已启用之后也是如此
- elasticsearch - Elasticsearch curator 在恢复操作期间恢复“.security”索引
- php - 替换 .php 文件的部分
- javascript - 语法错误:标识符直接在数字之后
- javascript - iframe 自动播放在移动设备中不起作用。如何使 youtube 自动播放在 ios 和 android 的移动设备上工作
- c++-cli - C++ CLI 通用函数
- google-apps-script - 谷歌脚本根据另一个包含公式的单元格更改单元格值
- mongodb - 属性参考 SpringBoot MongoDB 中未发现异常
- swiftui - iOS 15 上 SwiftUI 中的意外列表行为
- c# - 无法理解 C# 中的调用函数