2016-07-28 6 views
4

Ich versuche, eine Python-Webanwendung mithilfe der HTTP-API in die Firebase-DB schreiben zu lassen (ich verwende die neue Version von Firebase, die auf Google I/O 2016 vorgestellt wurde).Firebase DB HTTP API Auth: Wann und wie JWT-Token zu aktualisieren?

bisher Mein Verständnis ist, dass die spezifische Art von Schreib ich mit einer POST-Anfrage an eine URL dieses Typs zu erreichen, möchten wird:

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

Was mir fehlt ist die Auth-Teil: Wenn ich es richtig verstanden habe, sollte ein JWT im HTTP-Autorisierungs-Header als Authorization : Bearer {token} übergeben werden.

Also habe ich ein Dienstkonto erstellt, seinen privaten Schlüssel heruntergeladen und zum Generieren der JWT verwendet, es zu den Anforderungsheadern hinzugefügt und die Anforderung erfolgreich in die Firebase-DB geschrieben.

Jetzt ist der JWT abgelaufen und alle ähnlichen Anfragen an die Firebase-DB sind fehlgeschlagen.

Natürlich sollte ich ein neues Token erzeugen, aber die Frage ist: Ich erwartete nicht, Token-Generierung und aktualisieren mich selbst, die meisten HTTP-APIs, die ich gewohnt bin, nur einen statischen API-Schlüssel in der Anfrage übergeben werden meine webapps konnten also relativ einfach gehalten werden, indem einfach die stati api key string zur anfrage hinzugefügt wurde.

Wenn ich mich um Tokenerzeugung und -ablauf kümmern muss, muss die Webapp-Logik komplexer werden (weil ich das Token speichern müsste, prüfen, ob es noch gültig ist und ein neues erzeugt, wenn nicht) Ich könnte nur ein neues Token für jede Anfrage generieren (aber macht das wirklich Sinn?).

Ich würde gerne wissen, ob es in dieser Hinsicht eine Best Practice gibt oder ob etwas in der Dokumentation zu diesem Thema fehlt.

Danke, Marco


NACHTRAG

Dies ist der Code, den ich zur Zeit renne:

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) 

Zeit für jede Anforderung eine neue JWT erzeugt wird. Es scheint mir nicht optimal zu sein. Ist es möglich, ein Token zu generieren, das nicht abläuft?

+0

Vermutlich ist dies für serverseitigen Zugriff? Was Sie wahrscheinlich am ehesten tun möchten, ist ein Google-Zugriffstoken, das von einem Dienstkonto generiert wird. [Hier ist ein Beispiel] (http://stackoverflow.com/questions/37539066/how-to-authenticate-in-ruby-via-rest-api/38535125#38535125), wie es in Ruby zu tun ist. –

+0

Ja, es ist für den serverseitigen Zugriff. Was ich getan habe, wurde im Fragetext hinzugefügt. Obwohl ich immer noch das Gefühl habe, dass es nicht optimal ist, da ich bei jeder Anfrage ein neues JWT erzeuge. Für den serverseitigen Zugriff hatte ich gehofft, dass ein statisches (nicht auslaufendes) Token verwendet werden könnte. –

+0

Ab dem 3.x SDK erlauben wir aus Sicherheitsgründen kein einziges langlebiges Bearer-Token mehr. –

Antwort

0

Danke für das Codebeispiel. Ich habe es funktioniert besser mit der credentials.authorize-Funktion, die eine authentifizierte Wrapper für http erstellt.

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)