Firebase - 根据角色阻止身份验证

时间:2018-02-01 22:01:24

标签: javascript firebase firebase-realtime-database promise firebase-authentication

我正在开发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块,但仍然会进行身份验证。有没有办法阻止它?

1 个答案:

答案 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,但这只是美观的,并且在客户端上无法信任应该强制访问服务器端。