服务帐户的 Firebase 安全规则

问题描述 投票:0回答:1

我遇到了一个奇怪的错误: 我正在为我的数据库编写 firestore 规则,我意识到我的 BE(在节点中,部署在 Google 的云运行上)由于访问被拒绝问题而停止工作。这对我来说似乎很奇怪,根据我的所有评估,从 BE 登录,因此使用 SDK 用户不应验证这些规则。此外,通过将规则设置为完全开放,API 可以重新开始工作。此时我担心问题出在我如何设置服务器端服务帐户的身份验证...所以我询问您的观点

firebase 配置

import { getAuth } from "firebase/auth";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore/lite";
import stripe from "stripe";
import dotenv from "dotenv";
dotenv.config();
// Firebase configuration object containing API keys and other credentials
const firebaseConfig = {
  apiKey: process.env.API_KEY, // API key for accessing Firebase services
  authDomain: process.env.AUTH_DOMAIN, // Domain for authentication
  projectId: process.env.PROJECT_ID, // ID of the Firebase project
  storageBucket: process.env.STORAGE_BUCKET, // Storage bucket for Firebase storage
  messagingSenderId: process.env.MESSAGING_SENDER_ID, // Sender ID for Firebase Cloud Messaging
  appId: process.env.APP_ID, // ID of the Firebase application
};
// Initialize Firebase app with the provided configuration
const app = initializeApp(firebaseConfig);
// Get the authentication instance from the Firebase app
export const auth = getAuth(app);
// Get the Firestore database instance from the Firebase app
export const db = getFirestore(app);

// Initialize Stripe with the private key from the environment variables
export const STRIPE = new stripe(process.env.STRIPE_PRIVATE_KEY);

服务帐号

import admin from "firebase-admin";
// Defining service account configuration object using environment variables
const SERVICE_ACCOUNT = {
  type: process.env.SERVICE_ACCOUNT,
  project_id: process.env.PROJECT_ID,
  private_key_id: process.env.PRIVATE_KEY_ID,
  private_key: process.env.PRIVATE_KEY.replace(/\\n/g, "\n"), // Replacing escaped newline characters
  client_email: process.env.CLIENT_EMAIL,
  client_id: process.env.CLIENT_ID,
  auth_uri: process.env.AUTH_URI,
  token_uri: process.env.TOKEN_URI,
  auth_provider_x509_cert_url: process.env.AUTH_PROVIDER,
  client_x509_cert_url: process.env.CLIENT_CERT_URL,
  universe_domain: process.env.UNIVERSE_DOMAIN,
};

// Initializing Firebase Admin SDK with service account credentials
export default admin.initializeApp({
  credential: admin.credential.cert(SERVICE_ACCOUNT),
  serviceAccountId: process.env.CLIENT_EMAIL,
});

一个 API 示例

import {
    or,
    and,
    doc,
    query,
    where,
    getDoc,
    getDocs,
    deleteDoc,
    updateDoc,
    collection,
  } from "firebase/firestore/lite";
  import {
    generateToken,
    createResponse,
    createCustomToken,
    sendErrorResponse,
    returnErrorResponse,
    decryptPasswordFunction,
  } from "../../utils/utils.js";
  import {
    SUCCESS,
    EVENT_EXPIRED,
    OTP_INCORRECT,
    LOG_IN_SUCCESS,
    USER_NOT_FOUND,
    NOT_AUTHORISED,
    OTP_TIME_EXPIRED,
    EVENT_NOT_EXISTS,
    EVENT_NOT_ACTIVE,
    PASSWORD_MISMATCH,
    UNAUTHENTICATED_USER,
    EMAIL_OR_PHONE_NUMBER_REQUIRED,
    NOT_REGISTER_WITH_EMAIL_PASSWORD,
    USER_NOT_ACTIVE,
  } from "../../constants/responseConstants.js";
  import {
    SUCCESS_CODE,
    VALIDATION_ERROR_CODE,
    BAD_REQUEST_ERROR_CODE,
  } from "../../constants/statusConstants.js";
  import moment from "moment";
  import admin from "../../constants/serviceAccount.js";
  import { db } from "../../constants/fireBaseConfig.js";
  import { JWT, USER_ROLE, COLLECTION } from "../../constants/constant.js";
  import { loginValidator, languageValidator } from "../../shared/validator.js";
  
  //Login function appears to handle user authentication
  export const login = async (request, response) => {
    console.info("Starting execution of the login function ", request);
    // Define Firestore collections
    const USERS = collection(db, COLLECTION.USER);
    const OTPS = collection(db, COLLECTION.OTP);
    const EVENTS = collection(db, COLLECTION.EVENT);
    const APP_INFOS = collection(db, COLLECTION.AAP_INFO);
    try {
      const { body } = request;
      // Validate request language
      let languageValue = languageValidator().validate(request.query);
      const { respose_language } = languageValue.value;
      // Validate request body data
      const VALIDATE_DATA = loginValidator().validate(body);
      const { error, value } = VALIDATE_DATA;
      // Return validation error response if validation fails
      if (error)
        return await sendErrorResponse(
          response,
          VALIDATION_ERROR_CODE,
          error.details[0].message,
          respose_language
        );
      // Destructure validated values
      const { password, phone_number, otp, email } = value;
      // Check for required fields
      if (
        (body?.email && body?.phone_number) ||
        (!body?.email && !body?.phone_number)
      )
        return await sendErrorResponse(
          response,
          BAD_REQUEST_ERROR_CODE,
          EMAIL_OR_PHONE_NUMBER_REQUIRED,
          respose_language
        );
      let userQuery, userSnapShot,eventData;
      // Handle email case
      if (email) {
        userQuery = query(USERS, where("email", "==", email));
        userSnapShot = await getDocs(userQuery);
      }

错误

@firebase/firestore: Firestore (10.11.1_lite): RestConnection RPC 'RunQuery' 0x88991bb1 failed with error:  [FirebaseError: Request failed with error: Missing or insufficient permissions.] {
  code: 'permission-denied',
  customData: undefined,
  toString: [Function (anonymous)]
} url:  https://firestore.googleapis.com/v1/projects/app-power-bank/databases/(default)/documents:runQuery request: {
  structuredQuery: {
    from: [ { collectionId: 'users' } ],
    where: {
      fieldFilter: {
        field: { fieldPath: 'email' },
        op: 'EQUAL',
        value: { stringValue: '[email protected]' }
      }
    },
    orderBy: [ { field: { fieldPath: '__name__' }, direction: 'ASCENDING' } ]
  }
}
Error occured in login function:  [FirebaseError: Request failed with error: Missing or insufficient permissions.] {
  code: 'permission-denied',
  customData: undefined,
  toString: [Function (anonymous)]
}

请告诉我你的观点..

node.js firebase express google-cloud-platform google-cloud-firestore
1个回答
0
投票

根据我的阅读,您的帖子中有相当多的混乱之处。 您将展示 Firebase Client SDK(以及 Firestore 的“lite”版本)的使用以及 Firebase Admin SDK 的使用。

对于客户端 SDK 的使用,您没有显示该库如何进行身份验证。 您显示的是通过 Admin SDK 使用服务帐户,但这与 Firebase 的连接与客户端 SDK 的连接不同。

我以前见过很多这种混乱的情况。 请注意,Admin SDK(使用服务帐户)在“特权模式”(或“根模式”或“上帝模式”)下运行,并且不与 Firebase 身份验证服务中的用户帐户关联。 使用 Admin SDK(或更具体地说是“特权模式”)绕过了所有 Firebase 安全规则。

但是Client SDK是供“最终用户”使用的。 其用途适用于将根据 Firebase 身份验证进行身份验证的用户,并通过客户端 SDK 调用 Firebase 安全规则。

您上面的代码片段并不表明(Firebase Client SDK)代码如何进行身份验证。

如果担心您混淆了管理和客户端 SDK,以及它们如何工作/它们在身份验证和安全规则方面的行为方式。

© www.soinside.com 2019 - 2024. All rights reserved.