Cir*_*les 5 python oauth firebase python-cryptography firebase-admin
我正在使用该库开发带有 Firestore 实时数据库的 Python Web 应用程序firebase_admin。Firestore 密钥采用包含 10 个变量的 .json 文件形式。但是,我想将其中一些变量存储为环境变量,这样它们就不会公开可见。因此,我不使用 Firebase SDK .json 文件,而是使用该文件的元素创建自己的字典。字典看起来像这样,所有内容都是直接从 .json 文件复制的:
my_credentials = {
"type": "service_account",
"project_id": "bookclub-b2db5",
"private_key_id": os.environ.get("PRIVATE_KEY_ID"),
"private_key": os.environ.get("PRIVATE_KEY"),
"client_email": os.environ.get("CLIENT_EMAIL"),
"client_id": os.environ.get("CLIENT_ID"),
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": os.environ.get("AUTH_PROVIDER_X509_CERT_URL"),
"client_x509_cert_url": os.environ.get("AUTH_PROVIDER_X509_CERT_URL")
}
Run Code Online (Sandbox Code Playgroud)
我已将私钥设置为PRIVATE_KEY环境变量。私钥大致是这样的(这里的字符是组成的):
"-----BEGIN PRIVATE KEY-----\nEW8nYP9T840Sb8tQMi\nhZ(...MORE CHARACTERS HERE...)EW8nYP9T840Sb8tQMi/EW8nYP9T840Sb8tQMi\EW8nYP9T840Sb8tQMi/EW8nYP9T840Sb8tQMi=\n-----END PRIVATE KEY-----\n"
Run Code Online (Sandbox Code Playgroud)
然后,我尝试从这些凭据创建 Firebase 证书并初始化应用程序
cred = firebase_admin.credentials.Certificate(my_credentials)
firebase_admin.initialize_app(cred, {'databaseURL': 'https://myapp.firebasedatabase.app/'})
Run Code Online (Sandbox Code Playgroud)
然而,事实证明 PRIVATE_KEY 环境变量不可读(无法反序列化),并且会抛出错误:
Traceback (most recent call last):
File "C:\Users\jarem\Desktop\data_science\python-working-directory\_MyApps\BookClub2.0\venv\lib\site-packages\firebase_admin\credentials.py", line 96, in __init__
self._g_credential = service_account.Credentials.from_service_account_info(
File "C:\Users\jarem\AppData\Local\Programs\Python\Python39\lib\site-packages\google\oauth2\service_account.py", line 221, in from_service_account_info
signer = _service_account_info.from_dict(
File "C:\Users\jarem\AppData\Local\Programs\Python\Python39\lib\site-packages\google\auth\_service_account_info.py", line 58, in from_dict
signer = crypt.RSASigner.from_service_account_info(data)
File "C:\Users\jarem\AppData\Local\Programs\Python\Python39\lib\site-packages\google\auth\crypt\base.py", line 113, in from_service_account_info
return cls.from_string(
File "C:\Users\jarem\AppData\Local\Programs\Python\Python39\lib\site-packages\google\auth\crypt\_cryptography_rsa.py", line 133, in from_string
private_key = serialization.load_pem_private_key(
File "C:\Users\jarem\Desktop\data_science\python-working-directory\_MyApps\BookClub2.0\venv\lib\site-packages\cryptography\hazmat\primitives\serialization\base.py", line 22, in load_pem_private_key
return ossl.load_pem_private_key(data, password)
File "C:\Users\jarem\Desktop\data_science\python-working-directory\_MyApps\BookClub2.0\venv\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py", line 921, in load_pem_private_key
return self._load_key(
File "C:\Users\jarem\Desktop\data_science\python-working-directory\_MyApps\BookClub2.0\venv\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py", line 1189, in _load_key
self._handle_key_loading_error()
File "C:\Users\jarem\Desktop\data_science\python-working-directory\_MyApps\BookClub2.0\venv\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py", line 1248, in _handle_key_loading_error
raise ValueError(
ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=503841036, lib=60, reason=524556, reason_text=b'error:1E08010C:DECODER routines::unsupported')])
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\jarem\Desktop\data_science\python-working-directory\_MyApps\BookClub2.0\main.py", line 71, in <module>
cred = credentials.Certificate(my_credentials)
File "C:\Users\jarem\Desktop\data_science\python-working-directory\_MyApps\BookClub2.0\venv\lib\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: "('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=503841036, lib=60, reason=524556, reason_text=b'error:1E08010C:DECODER routines::unsupported')])"
Run Code Online (Sandbox Code Playgroud)
所有其他环境变量似乎都是可读的。它可能与环境变量的格式有关,但我不知道到底是什么。什么都不起作用,我不知道这个错误的原因。我在 Windows 11 上工作并使用cryptography版本 35.0.0。
如何解决此问题以提取私钥?
更新: 我发现当我直接打印私钥时,它会打印新行,例如:
-----BEGIN PRIVATE KEY-----
ZGVNvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDtuzZSrBuf4Lv3
DJTPJDj34jfknDJOJjfpitjrpZGVNvgIBADANBgkqhkiG9w0BAQZGVNvgI+DIome
ZGVNvgIBADANBgkqhkiG9w0BAQVdFkqJd5j53tZFgX5VLOf7g23/Zvgq+BFIHe34
(...MORE LINES HERE...)
-----END PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
但是,当我打印 获得的私钥时os.environ.get('PRIVATE KEY'),没有出现换行符:
-----BEGIN PRIVATE KEY-----ZGVNvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDtuzZSrBuf4Lv3\nDJTPJDj34jfknDJOJjfpitjrpZGVNvgIBADANBgkqhkiG9w0BAQZGVNvgI+DIome\nZGVNvgIBADANBgkqhkiG9w0BAQVdFkqJd5j53tZFgX5VLOf7g23/Zvgq+BFIHe34\n(...MORE CHARACTERS HERE...)-----END PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
环境变量系统读取“\n”似乎存在问题。但是,我仍然不知道如何克服这个错误。
Cir*_*les 11
我已经解决了问题:
To solve the problem with "\n" I had to replace the raw string "\n" with "\n", as (presumably) the environment variables return a raw string, which treats backslash () as a literal character. The solution looks as follows:
my_credentials = {
"type": "service_account",
"project_id": "bookclub-b2db5",
"private_key_id": os.environ.get("PRIVATE_KEY_ID"),
"private_key": os.environ.get("PRIVATE_KEY").replace(r'\n', '\n'), # CHANGE HERE
"client_email": os.environ.get("CLIENT_EMAIL"),
"client_id": os.environ.get("CLIENT_ID"),
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": os.environ.get("AUTH_PROVIDER_X509_CERT_URL"),
"client_x509_cert_url": os.environ.get("AUTH_PROVIDER_X509_CERT_URL")
}
Run Code Online (Sandbox Code Playgroud)
Now, everything works.
| 归档时间: |
|
| 查看次数: |
1978 次 |
| 最近记录: |