2016-07-28 49 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)