簡體   English   中英

在 GitHub 操作中驗證 Firebase 連接

[英]Authenticating Firebase connection in GitHub Action

背景

我有一個 Python 腳本,它從 Excel 文件中讀取數據,並將每一行作為單獨的文檔上傳到 Firestore 中的集合。 當我將 Excel 文件的新版本推送到 GitHub 時,我希望此腳本運行。

設置

我將必要的憑據放入 GitHub repo secrets 並設置以下工作流程以在推送到我的data/目錄時運行:

name: update_firestore

on:
  push:
    branches:
      - main
    paths:
      - data/**.xlsx

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: checkout repo content
        uses: actions/checkout@v2 # checkout the repository content to github runner.

      - name: setup python
        uses: actions/setup-python@v4
        with:
          python-version: '3.*' # install the latest python version

      - name: install python packages
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: execute python script
        env:
          TYPE: service_account
          PROJECT_ID: ${{ secrets.PROJECT_ID }}
          PRIVATE_KEY_ID: ${{ secrets.PRIVATE_KEY_ID }}
          PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
          CLIENT_EMAIL: ${{ secrets.CLIENT_EMAIL }}
          TOKEN_URI: ${{ secrets.TOKEN_URI }}
        run: python src/update_database.py -n ideas -delete -add

問題

我不斷收到以下錯誤:

Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.10.7/x64/lib/python3.10/site-packages/firebase_admin/credentials.py", line 96, in __init__
    self._g_credential = service_account.Credentials.from_service_account_info(
  File "/opt/hostedtoolcache/Python/3.10.7/x64/lib/python3.10/site-packages/google/oauth2/service_account.py", line 221, in from_service_account_info
    signer = _service_account_info.from_dict(
  File "/opt/hostedtoolcache/Python/3.10.7/x64/lib/python3.10/site-packages/google/auth/_service_account_info.py", line 58, in from_dict
    signer = crypt.RSASigner.from_service_account_info(data)
  File "/opt/hostedtoolcache/Python/3.10.7/x64/lib/python3.10/site-packages/google/auth/crypt/base.py", line 113, in from_service_account_info
    return cls.from_string(
  File "/opt/hostedtoolcache/Python/3.10.7/x64/lib/python3.10/site-packages/google/auth/crypt/_python_rsa.py", line 171, in from_string
    raise ValueError("No key could be detected.")
ValueError: No key could be detected.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/runner/work/IRIS/IRIS/src/update_database.py", line 9, in <module>
    import fire
  File "/home/runner/work/IRIS/IRIS/src/fire/__init__.py", line 35, in <module>
    cred = credentials.Certificate(create_keyfile_dict())
  File "/opt/hostedtoolcache/Python/3.10.7/x64/lib/python3.10/site-packages/firebase_admin/credentials.py", line 99, in __init__
    raise ValueError('Failed to initialize a certificate credential. '
ValueError: Failed to initialize a certificate credential. Caused by: "No key could be detected."
Error: Process completed with exit code 1.

我嘗試的解決方案

我嘗試了多種方法,包括我上面展示的方法,只是對每個秘密進行硬編碼,並將.json格式的憑據直接復制為一個秘密。 我知道有一些處理PRIVATE_KEY多行環境變量的問題。 我試過了:

  1. 直接從下載 firebase 提供的PRIVATE_KEY str 粘貼,其中包括\n
  2. 刪除轉義字符並格式化秘密,例如:
-----BEGIN PRIVATE KEY-----
BunC40fL3773R5AndNumb3r5
...
rAndomLettersANDNumb3R5==
-----END PRIVATE KEY-----

我覺得解決方案應該非常簡單,但一直在努力,我對這一切的了解有點有限。

先感謝您!

經過幾個小時的研究,我找到了一種將 Firestore 服務帳戶 JSON 存儲為 Github Secret 的簡單方法。

第 1 步:將您的服務帳戶 JSON 轉換為 base-64

讓我們將 base-64 編碼命名為 JSON SERVICE_ACCOUNT_KEY 有兩種方法可以獲取這個值:

方法一:使用命令行

cat path-to-your-service-account.json | base64 | xargs

這將返回代表編碼服務帳戶 JSON 的單行。復制此值。

方法二:使用python

import json
import base64


service_key = {
    "type": "service_account",
    "project_id": "xxx",
    "private_key_id": "xxx",
    "private_key": "-----BEGIN PRIVATE KEY-----\nxxxxx\n-----END PRIVATE KEY-----\n",
    "client_email": "xxxx.com",
    "client_id": "xxxx",
    "auth_uri": "xxxx",
    "token_uri": "xxxx",
    "auth_provider_x509_cert_url": "xxxx",
    "client_x509_cert_url": "xxxx"
}

# convert json to a string
service_key = json.dumps(service_key)

# encode service key
SERVICE_ACCOUNT_KEY= base64.b64encode(service_key.encode('utf-8'))

print(SERVICE_ACCOUNT_KEY)
# FORMAT: b'a_long_string'

只復制引號之間的值。 (復制a_long_string而不是b'a_long_string'

第 2 步:創建環境變量

我正在使用dotenv 庫來讀取環境變量。 您必須先使用pip install python-dotenv安裝它。 還要在您的requirements.txt中為 github 操作添加此依賴項。

  • 創建一個 Github 存儲庫機密SERVICE_ACCOUNT_KEY ,它將存儲 base-64 值。
  • 在你的 Github YML 文件中,添加環境變量:
      - name: execute py script 
        env:
          SERVICE_ACCOUNT_KEY: ${{ secrets.SERVICE_ACCOUNT_KEY }}
        run: python src/main.py 
  • 為了能夠在本地測試您的程序,您可能還想將SERVICE_ACCOUNT_KEY及其值添加到您的.env文件(應該位於項目的根目錄中)。 請記住將.env添加到您的.gitignore文件中,以避免在 Github 上暴露您的密鑰。

第 3 步:解碼服務密鑰

您現在需要在 Python 代碼中獲取SERVICE_ACCOUNT_KEY的值,並將該值轉換回 JSON。我正在使用dotenv庫獲取SERVICE_ACCOUNT_KEY的值。

import json
import base64
import os
from dotenv import load_dotenv, find_dotenv

# get the value of `SERVICE_ACCOUNT_KEY`environment variable
load_dotenv(find_dotenv())
encoded_key = os.getenv("SERVICE_ACCOUNT_KEY")

# decode
SERVICE_ACCOUNT_JSON = json.loads(base64.b64decode(encoded_key).decode('utf-8'))

# Use `SERVICE_ACCOUNT_JSON` later to initialse firestore db:
# cred = credentials.Certificate(SERVICE_ACCOUNT_JSON)
# firebase_admin.initialize_app(cred)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM