Вопрос или проблема
JSON файл сервисного аккаунта Firebase был загружен и доступен через переменную окружения в приложении NESTJS. Локально все работает хорошо (используя эти шаги https://dev.to/cfofiu/how-to-store-a-long-private-key-in-vercel-s-environment-variables-46f5)
Однако, когда я пытаюсь запустить приложение в облачном контейнере GCP, используя (переменные окружения или секретный менеджер), я получаю следующую ошибку
Не удалось разобрать закрытый ключ: Ошибка: Неверный формат сообщения PEM. Ошибка: Не удалось разобрать закрытый ключ: Ошибка: Неверный формат сообщения PEM.
Попробовал все следующие варианты, но проблема остается прежней
- Доступ через секретный менеджер по переменной и замена
process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n')
- Доступ через переменную окружения
- Доступ через секретный менеджер/переменную окружения и размещение всего JSON как строки и разбор его через JSON.parse
Я также пробовал множество вариантов, однако все сборки завершались с той же ошибкой. Есть ли способ напрямую из Cloud Run получить доступ к аккаунту Firebase, чтобы решить эту проблему
Это проблема с тем, как закрытый ключ разбирается firebase-admin. Мне пришлось извлечь закрытый ключ как отдельный secretKey и добавить его отдельно
credential: admin.credential.cert({
...JSON.parse(process.env.KEY),
privateKey: process.env.PRIVATE.split(
String.raw`\n`
).join("\n"),
}),
Ответ или решение
Ошибка при доступе к PrivateKey Firebase через переменные окружения Cloud Run
При работе с GCP (Google Cloud Platform) и интеграцией Firebase в ваше приложение на NestJS, вы можете столкнуться с ошибкой: "Failed to parse private key: Error: Invalid PEM formatted message." Давайте разберемся с этой проблемой более подробно и предложим эффективное решение.
Причины возникновения ошибки
Эта ошибка возникает, когда Firebase Admin SDK не может правильно распарсить предоставленный закрытый ключ. Чаще всего это связано с неправильным форматированием ключа при его хранении в переменных окружения или секретах.
Когда вы загружаете JSON-ключ служебного аккаунта Firebase, закрытый ключ может содержать символы новой строки, которые неправильно обрабатываются при извлечении из переменной окружения. В отличие от локального окружения, где у вас могут быть более свободные условия для экранирования и форматирования, в GCP могут действовать более строгие правила.
Решение проблемы с PrivateKey
Во избежание этой проблемы я рекомендую следующую проверенную стратегию:
-
Сохраните закрытый ключ как отдельную переменную. Можно выделить закрытый ключ из JSON-файла и сохранить его в отдельной переменной (с секретом) или окружении:
{ "type": "service_account", "project_id": "your-project-id", "private_key_id": "your-private-key-id", "private_key": "-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY\n-----END PRIVATE KEY-----\n", ... }
-
Используйте корректный формат в коде. При доступе к переменным окружения убедитесь, что вы правильно экранируете символы новой строки. Вы можете использовать следующий код для настройки Firebase SDK:
const admin = require('firebase-admin'); const serviceAccount = JSON.parse(process.env.KEY); admin.initializeApp({ credential: admin.credential.cert({ ...serviceAccount, privateKey: process.env.PRIVATE.split(String.raw`\n`).join('\n'), }), });
-
Проверка переменных окружения. Убедитесь, что ваши переменные окружения правильно установлены в Cloud Run. Вы можете сделать это через консоль Google Cloud или командную строку gcloud. Если вы используете Secret Manager, убедитесь, что доступ к секретам настроен корректно.
-
Отладка. Если ошибка сохраняется, добавьте некоторые логи для проверки считываемых значений из переменных окружения. Убедитесь, что
process.env.PRIVATE
содержит правильный закрытый ключ с корректными символами новой строки.
Заключение
Правильное конфигурирование и хранение секретов в GCP критически важны для обеспечения безопасности вашего приложения. Убедитесь, что вы следуете описанным шагам, и ваша проблема с неправильным форматом закрытого ключа должна быть решена. Если у вас появились дополнительные вопросы или трудности, не стесняйтесь обращаться за дополнительной помощью в сообщество разработчиков или поддержке Google Cloud.