我尝试使用HTTP API向Firebase数据库写入Python webapp(我使用的是2016年Google I / O上展示的新版Firebase)。
到目前为止,我的理解是我想要完成的特定写入类型是对此类URL的POST请求:
https://my-project-id.firebaseio.com/{path-to-resource}.json
我缺少的是auth部分:如果我得到了正确的话,JWT应该作为Authorization : Bearer {token}
在HTTP Authorization标头中传递。
所以我创建了一个服务帐户,下载了私钥并用它来生成JWT,将其添加到请求标头中,并且请求成功写入Firebase DB。
现在JWT已经过期,并且对firebase DB的任何类似请求都失败了。
当然我应该生成一个新的令牌,但问题是:我不期望处理令牌生成并刷新自己,大多数HTTP API我以前只需要传递一个静态api密钥在请求中,只需将stati api密钥字符串添加到请求中,我的webapps就可以保持相对简单。
如果我必须处理令牌生成和过期,webapp逻辑需要变得更加复杂(因为我必须存储令牌,检查它是否仍然有效并在没有时生成新令牌),或者我可以为每个请求生成一个新令牌(但这真的有意义吗?)。
我想知道在这方面是否有最佳做法,或者我是否遗漏了有关此主题的文档中的内容。
谢谢, 马可
附录
这是我目前正在运行的代码:
import requests
import json
from oauth2client.service_account import ServiceAccountCredentials
_BASE_URL = 'https://my-app-id.firebaseio.com'
_SCOPES = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]
def _get_credentials():
credentials = ServiceAccountCredentials.from_json_keyfile_name('my_service_account_key.json', scopes=_SCOPES)
return credentials.get_access_token().access_token
def post_object():
url = _BASE_URL + '/path/to/write/to.json'
headers = {
'Authorization': 'Bearer '+ _get_credentials(),
'Content-Type': 'application/json'
}
payload = {
'title': title,
'message': alert
}
return requests.post(url,
data=json.dumps(payload),
headers=headers)
目前,每个请求都会生成一个新的JWT。它对我来说似乎不是最佳选择。是否有可能生成一个不会过期的令牌?
答案 0 :(得分:0)
感谢代码示例。我通过使用credentials.authorize函数更好地工作,该函数为http。
创建一个经过身份验证的包装器from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
import json
_BASE_URL = 'https://my-app-id.firebaseio.com'
_SCOPES = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]
# Get the credentials to make an authorized call to firebase
credentials = ServiceAccountCredentials.from_json_keyfile_name(
_KEY_FILE_PATH, scopes=_SCOPES)
# Wrap the http in the credentials. All subsequent calls are authenticated
http_auth = credentials.authorize(Http())
def post_object(path, objectToSave):
url = _BASE_URL + path
resp, content = http_auth.request(
uri=url,
method='POST',
headers={'Content-Type': 'application/json'},
body=json.dumps(objectToSave),
)
return content
objectToPost = {
'title': "title",
'message': "alert"
}
print post_object('/path/to/write/to.json', objectToPost)