Невозможно выдать себя за пользователя с помощью firebase-admin во время вызовов firestore - PullRequest
0 голосов
/ 07 августа 2020

На основании того, что здесь написано, они «олицетворяют пользователя» с новым экземпляром административного приложения Firebase, поэтому при выполнении записи / чтения правила безопасности будут срабатывать для этого пользователя.

https://firebase.google.com/docs/database/extend-with-functions

Я пытаюсь сделать то же самое, но для Firestore, но это не работает.

Цель

У меня есть чтение / запись в firestore go через серверную часть express, размещенную как облачную функцию. Я не хочу вводить ручные правила безопасности в этом бэкэнде.

Я хочу, чтобы экземпляр приложения firebase-admin вел себя «как пользователь», чтобы правила безопасности firestore запускались соответствующим образом, и я мог унифицировать свои безопасность в правилах безопасности.

Вот код, который я использую:

1. получить параметры приложения администратора

export function getLocalAdminAppOptions(): admin.AppOptions {
    // we are running locally
    const serviceAccount: admin.ServiceAccount = {
        clientEmail: CLIENT_EMAIL,
        projectId: PROJECT_ID,
        privateKey: (PRIVATE_KEY || "").replace(/\\n/g, "\n")
    }
    return {
        credential: admin.credential.cert(serviceAccount),
        databaseURL: DATABASE_URL
    }
}

2. добавьте параметры олицетворения и создайте приложение администратора

import * as Admin from "firebase-admin"
import * as Functions from "firebase-functions"

const appOptions = getLocalAdminAppOptions()
const token: Admin.auth.DecodedIdToken = await Admin.auth().verifyIdToken(req.idToken)
const authOverwrite: Functions.EventContext["auth"] = {
    token,
    uid: req.authUser.uid
}
appOptions.databaseAuthVariableOverride = authOverwrite
const uniqueAppName = "adminAppAsUser:" + req.authUser.uid
const adminAppAsUser = Admin.initializeApp(appOptions, uniqueAppName)

3. сделать вызов firestore с экземпляром приложения олицетворения

const snap = await adminAppAsUser
  .firestore()
  .collection(`test`)
  .doc("test")
  .get()

return snap.data()

Проблема:

Кажется, что adminAppAsUser по-прежнему является приложением администратора с полными правами доступа, игнорируя правила безопасности.

Неверный обходной путь

Мне удалось найти «хакерский» обходной путь: создать новый экземпляр Firebase для Интернета внутри моего бэкэнда, подписать с помощью специального токена и использовать его для доступа к firestore.

Проблемы с этим обходным путем: signInWithCustomToken занимает 800 мсек каждый раз, когда я запускаю облачную функцию!

Код обходного пути:

const uniqueAppName = "adminAppAsUser:" + req.authUser.uid
const adminAppAsUser = Firebase.initializeApp(configs.dev, uniqueAppName)
const token = await Admin.auth().createCustomToken(req.authUser.uid)
await adminAppAsUser.auth().signInWithCustomToken(token)

1 Ответ

0 голосов
/ 07 августа 2020

Я пытаюсь сделать то же самое, но для Firestore, но это не работает.

Это не поддерживается вообще. Олицетворение, которое вы можете получить с помощью RTDB, не работает для Firestore.

При использовании любого из внутренних SDK для Firestore привилегии учетной записи службы, используемой для ее инициализации, всегда будут обходить правила безопасности и зависят от Google Cloud IAM разрешения вместо этого.

См. также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...