Serge Serge - 4 years ago 223
Python Question

Fail to authorize using ServiceAccountCredentials for calls to Firebase (REST API / python)

I always get 401 error trying to fetch Firebase resource and passing access token. I cannot get what am I doing wrong.

So I follow this manual: I created service account, then create

ServiceAccountCredentials
object, passing scope
https://www.googleapis.com/auth/firebase
. Then I get token from created object and pass it as
access_token
query parameter, as stated in docs, trying fetch data from my Firebase DB. But I keep getting 401 error (unauthorized). Token, by the way, seems to be invalid if check in tool like jsonwebtoken (probably I do something wrong there / provide incorrect secret?).

So, my code is like this:

import httplib2
from oauth2client.service_account import ServiceAccountCredentials

credentials = ServiceAccountCredentials.from_json_keyfile_name('/path/auth.json', scopes=['https://www.googleapis.com/auth/firebase'])
token = credentials.get_access_token().access_token
http = httplib2.Http()
result = http.request('https://my-project.firebaseio.com/srv.json?access_token=%s' % token)


And result body always is
{"error" : "Unauthorized request."}
along with 401 HTTP status code.

Answer Source

I think your scopes were not sufficient. Here is a end to end example I got working using credentials and the credentials.authorize http wrapper

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)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download