首页 > 解决方案 > 在使用 Firebase 会话 cookie 时检测 Firestore 安全规则中经过身份验证的用户

问题描述

Firestore 安全规则有一个小问题。我有一个使用 Firebase 和 Firestore 的带有自定义 API 的 React/Redux SPA。

我目前使用 Firebase 官方文档 ( https://firebase.google.com/docs/auth/admin/manage-cookies )中描述的会话 cookie 。因此,当我登录时,cookie 被设置并与后续请求一起发送到 API,这没有问题。

但是现在当我使用会话 cookie 系统登录时,Firestore 规则不允许我读取或写入带有“权限被拒绝”错误的数据,因为 Firestore 请求的 request.auth 对象不再使用会话设置饼干系统...

如何检测用户是否通过我的 Firestore 安全规则中的会话 cookie 进行了身份验证?

使用会话 cookie 在我的 Firebase 外部 API 中登录路由:

login(req, res) {
auth.setPersistence(firebase.auth.Auth.Persistence.NONE);
auth.signInWithEmailAndPassword(req.query.email, req.query.password)
  .then((response) => response.user.getIdToken().then((idToken) => {
    const expiresIn = 60 * 15 * 1000;
    admin.auth().createSessionCookie(idToken, { expiresIn })
      .then((sessionCookie) => {
        const options = { maxAge: expiresIn, httpOnly: true, secure: !!process.env.NODE_ENV === 'production' };
        res.cookie('session', sessionCookie, options);
        auth.signOut();
        res.json(response);
      }, () => {
        res.status(401).write('Error while verifying token.');
      });
  })).catch((err) => {
    console.error(err);
  });
},

基本用户使用 Firestore 获得相同的 API;在请求标头中设置 cookie 登录后立即调用:

get(req, res) {
  const { uid } = req;
  db.collection('users').doc(uid).get().then((doc) => {
    res.json(doc.data());
  })
  .catch((err) => {
    console.log(req.path);
    console.error(err);
    res.json(err);
  });
},

Firestore 安全规则中的权限被拒绝错误:

Error [FirebaseError]: Missing or insufficient permissions.

我需要使用的旧 Firestore 安全规则:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    function isSignedIn() {
      return request.auth != null;
    }
    match /users/{userId} {
      allow create, update, get: if isSignedIn();
    }
    match /medic/{medicId} {
      allow create, read: if isSignedIn();
    }
  }
}

非常感谢!

标签: firebasecookiesgoogle-cloud-firestorefirebase-authenticationfirebase-security

解决方案


好的,所以我在这里找到了解决方案。我没有在我的服务器端 API 中使用 Firebase Admin SDK,这就是检查 Firestore 安全规则的原因,因为系统认为这是一个客户端请求。

我必须限制 Firestore 安全规则中的所有操作,然后使用 Firebase Admin SDK 在 API 中执行我的数据库操作(显然我需要自己检查数据和身份验证,因为不再使用 Firestore 安全规则;但这已经是案例感谢 Firebase 会话 cookie)

随着您深入探索安全规则,您最终会发现来自 Firebase Admin SDK 的请求不受规则限制。Admin SDK 使用服务帐户进行初始化,这使 SDK 可以完全访问您的数据。在 Firebase 实时数据库中,您可以将 Admin SDK 的权限限定为用户 ID,并照常执行规则。但其他产品,尤其是 Google Cloud Firestore,尚不支持此功能。在实现服务器端数据访问操作时,您应该注意这一点。

见:https ://firebase.googleblog.com/2019/03/firebase-security-rules-admin-sdk-tips.html


推荐阅读