【发布时间】:2021-04-25 14:03:48
【问题描述】:
TLDR;
- 根据自定义声明设置 Firestore 安全规则。
- Cloud Firestore 用户是通过手机身份验证创建的。
- 云功能在创建用户时触发并添加自定义声明角色 - 管理员。在实时数据库中更新条目以指示索赔更新。
- 在客户端收听实时数据库的更新,并在自定义声明更新后致电
user.getIdToken(true);。 - 能够在代码中看到添加的自定义声明。
- 由于缺少权限(自定义声明),无法读取 Firestore 中的文档。
- 刷新浏览器页面,现在可以阅读文档了。
我有一个云功能,可以在用户创建时添加自定义声明 role - admin。
exports.processSignUp = functions.auth.user().onCreate((user) => {
const customClaims = {
role: 'admin',
};
// Set custom user claims on this newly created user.
return admin.auth().setCustomUserClaims(user.uid, customClaims)
.then(() => {
// Update real-time database to notify client to force refresh.
const metadataRef = admin.database().ref("metadata/" + user.uid);
// Set the refresh time to the current UTC timestamp.
// This will be captured on the client to force a token refresh.
return metadataRef.set({refreshTime: new Date().getTime()});
})
.catch(error => {
console.log(error);
});
});
我在实时数据库中侦听更改事件,以检测用户自定义声明的更新。
let callback = null;
let metadataRef = null;
firebase.auth().onAuthStateChanged(user => {
// Remove previous listener.
if (callback) {
metadataRef.off('value', callback);
}
// On user login add new listener.
if (user) {
// Check if refresh is required.
metadataRef = firebase.database().ref('metadata/' + user.uid + '/refreshTime');
callback = (snapshot) => {
// Force refresh to pick up the latest custom claims changes.
// Note this is always triggered on first call. Further optimization could be
// added to avoid the initial trigger when the token is issued and already contains
// the latest claims.
user.getIdToken(true);
};
// Subscribe new listener to changes on that node.
metadataRef.on('value', callback);
}
});
我在 Cloud Firestore 上有以下安全规则。
service cloud.firestore {
match /databases/{database}/documents {
match /{role}/{document=**} {
allow read: if request.auth != null &&
request.auth.token.role == role;
}
}
}
创建用户后,我的云函数触发并添加自定义声明role = admin。
user.getIdToken(true); 的结果是令牌在我的客户端上刷新,我可以看到设置的自定义声明。
当我尝试获取用户应该能够阅读的文档时,我获得了云防火墙安全规则拒绝的权限。
当我刷新浏览器页面时,我可以读取路径中的文档。
我希望能够访问 firebase 文档而无需刷新浏览器。有这种可能吗?
有人可以告诉我我的方法/期望有什么问题吗?
【问题讨论】:
标签: firebase google-cloud-firestore firebase-security