2016-07-28 90 views
4

我正在尝试使用HTTP API将Python webapp写入Firebase数据库(我正在使用在Google I/O 2016上提供的新版Firebase)。Firebase DB HTTP API Auth:何时以及如何刷新JWT令牌?

我的理解至今是写的具体类型,我想完成与POST请求,这种类型的网址进行的:

https://my-project-id.firebaseio.com/{path-to-resource}.json

什么,我缺少的是auth部分:如果我正确地得到它,应该在HTTP授权标头中传递一个JWT作为Authorization : Bearer {token}

因此,我创建了一个服务帐户,下载了它的私钥并将其用于生成JWT,将其添加到请求标头并将请求成功写入Firebase DB。

现在JWT已过期,并且任何类似的对Firebase DB的请求都失败。

当然,我应该生成一个新的令牌,但问题是:我并不期望自己处理令牌生成和刷新,大多数HTTP API我只需要在请求中传递一个静态API密钥所以我的webapps可以保持相对简单,只需将stati api密钥字符串添加到请求中即可。

如果我必须照顾令牌生成和到期,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

推测这是用于服务器端访问?您实际上最想做的事情是使用从服务帐户生成的Google访问令牌。 [这是一个例子](http://stackoverflow.com/questions/37539066/how-to-authenticate-in-ruby-via-rest-api/38535125#38535125)如何在Ruby中做到这一点。 –

+0

是的,它用于服务器端访问。问题文本中添加了我最终做的事情。虽然我仍然觉得这不是最佳的,因为我每生成一个新的JWT请求。对于服务器端访问,我希望可以使用静态(非过期)令牌。 –

+0

从3.x SDK开始,由于安全原因,我们不再允许单个长生命持票人令牌。 –

回答

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)