我正在开发Android和Web应用程序。在Web上,只有管理员用户才能登录。我想阻止非管理员用户登录Web应用程序。
我发现使其“工作”的唯一方法是在我获得有关其角色的信息时注销用户。问题是这会使页面闪烁,因为用户在几秒钟内进行了身份验证。我想阻止登录,但是一旦登录,我只能访问User对象。这是我目前的代码:
export function login (email, pw) {
return firebaseAuth.signInWithEmailAndPassword(email, pw).then(checkRole)
}
function checkRole (user) {
return ref.child(`UserRoles/${user.uid}`).once('value').then(snapshot => {
let isAdmin = (snapshot.val() && snapshot.val().admin)
if (!isAdmin) throw new Error('User is not admin')
}).then(() => user)
}
虽然这会触发承诺的catch
块,但仍然会进行身份验证。有没有办法阻止它?
答案 0 :(得分:2)
您最好使用您在用户上设置的custom user claims来定义用户角色。
您可以通过Admin SDK设置自定义声明:
admin.auth().setCustomUserClaims(uid, {role: 'admin'}).then(() => {
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.
});
然后,您可以通过安全规则强制执行访问,而无需进行任何查找:
{
"rules": {
"data": {
"$user_id": {
".read": "$user_id === auth.uid && auth.token.role === 'admin'",
".write": "$user_id === auth.uid && auth.token.role === 'admin'"
}
}
}
}
这是关键,角色访问必须在服务器端强制执行。
在客户端,您可以获取ID令牌currentUser.getIdToken()
和base64解码有效负载,以检查声明中的角色,以相应地更新UI,但这只是美观的,并且在客户端上无法信任应该强制访问服务器端。