首页 > 解决方案 > Firebase 自定义声明未在规则中更新

问题描述

我试图防止存储滥用。我的目标是每天限制用户上传操作。所以我部署了一个存储 onFinalize 触发器,一旦文件上传,该函数检测一个计数器,使用 firestore 是否达到限制。如果是,像这样将毫秒存储到 CustomUserClaims:

//the user need to wait after this time to continue upload files (timeToUnlock = currentTime + additionalTime)
setCustomUserClaims(uid, {
    timeToUnlock: 1570509112055
})

并在规则中进行比较

allow create: if request.time.toMillis() >= request.auth.token.timeToUnlock;

但是每次 setCustomUserClaims 我需要注销并再次登录客户端以更新声明或声明不会更新它只是保持以前的值。我打印 customClaims 到控制台参数已更新但似乎规则中的参数没有更新。任何人都有更好的主意解决这个问题?因为如果这不起作用,我不知道要阻止这种情况,感谢您的帮助。

console.log((await admin.auth().getUser(uid)).customClaims);

标签: firebasefirebase-authenticationgoogle-cloud-storagefirebase-securityfirebase-admin

解决方案


您所看到的是预期的行为。您更新声明的后端代码无法强制客户端立即查看这些声明。根据文档

通过 Admin SDK 在用户上修改新声明后,它们会通过以下方式通过 ID 令牌传播到客户端的经过身份验证的用户:

  • 修改自定义声明后,用户登录或重新验证。结果颁发的 ID 令牌将包含最新的声明。
  • 旧令牌过期后,现有用户会话会刷新其 ID 令牌。
  • 通过调用 currentUser.getIdToken(true) 强制刷新 ID 令牌。

您可以做的最好的事情是编写您的客户端,以便服务器上的更改触发客户端上的更改以强制刷新将使用新声明的 ID 令牌。但这并不一定会阻止客户端使用旧令牌,直到它最终过期。

如果您想限制上传,在每次存储上传时使用 Cloud Functions 触发器会更加安全可靠,检查文件是否应该被允许,如果文件违反您的规则则删除文件。


推荐阅读