ozgur/python-firebase

exception: Failed to validate Mac

windgo opened this issue ยท 11 comments

After I set a rule which allow some user to write to Firebase, a exception was thrown.
It is ok with the iOS SDK, but python will crash.

code:

    f = firebase.FirebaseApplication('https://glowing-fire-xxxx.firebaseIO.com', None)
    f.authentication = firebase.FirebaseAuthentication('xxxx', 'xxxx@hotmail.com')
    ref = "/v/2/vd"
    f.put(ref,"2016","a:3:5") // throw exception

the rule:

{
    "rules": {
        ".read": true,
        "v":{
           ".read": true,
           ".write": "auth != null&&auth.uid=='xxx-xxx-af2d'"
        }
    }
}

exception:

_content = {str} '{\n  "error" : "Failed to validate MAC."\n}\n'
_content_consumed = {bool} True
apparent_encoding = {str} 'ascii'
connection = {HTTPAdapter} <requests.adapters.HTTPAdapter object at 0x110fc8790>
content = {str} '{\n  "error" : "Failed to validate MAC."\n}\n'
cookies = {RequestsCookieJar} <RequestsCookieJar[]>
elapsed = {timedelta} 0:00:01.277145
encoding = {str} 'utf-8'
headers = {CaseInsensitiveDict} CaseInsensitiveDict({'content-length': '42', 'strict-transport-security': 'max-age=31556926; includeSubDomains; preload', 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-cache'})
history = {list} []
links = {dict} {}
ok = {bool} False
raw = {HTTPResponse} <requests.packages.urllib3.response.HTTPResponse object at 0x110fdffd0>
reason = {str} 'Bad Request'
request = {PreparedRequest} <PreparedRequest [PUT]>
status_code = {int} 400
text = {unicode} u'{\n  "error" : "Failed to validate MAC."\n}\n'
url = {unicode} u'https://xxx.firebaseIO.com/v/2/vd/2016.json?auth=eyJhbGciOiAiSFMyNTYiLCAidasdfG1pbiI6IGZhbHNlLCAiZGVidWciOiBmYWxzZSwgImlhdCI6IDE0NTcxMzI2MjEsICJkIjogeyJkZWJ1ZyI6IGZhbHNlLCAiYWRtaW4iOiBmYWxzZSwgImVtYWlsIjogImltcW

Traceback

Traceback (most recent call last):
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 2411, in <module>
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1802, in run
    launch(file, globals, locals)  # execute the script
  File "/Users/xxx/script/xxxx.py", line 373, in <module>
    f.put(ref,xxx,xxx)
  File "/Library/Python/2.7/site-packages/firebase/decorators.py", line 19, in wrapped
    return f(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/firebase/firebase.py", line 302, in put
    connection=connection)
  File "/Library/Python/2.7/site-packages/firebase/decorators.py", line 19, in wrapped
    return f(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/firebase/firebase.py", line 72, in make_put_request
    response.raise_for_status()
  File "/Library/Python/2.7/site-packages/requests/models.py", line 683, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request
Traceback (most recent call last):
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 2411, in <module>
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1802, in run
    launch(file, globals, locals)  # execute the script
  File "/Users/huifengqi/workspace/xxx/script/myFile.py", line 373, in <module>
    f.put(ref,ds2,hp.retVerse)
  File "/Library/Python/2.7/site-packages/firebase/decorators.py", line 19, in wrapped
    return f(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/firebase/firebase.py", line 302, in put
    connection=connection)
  File "/Library/Python/2.7/site-packages/firebase/decorators.py", line 19, in wrapped
    return f(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/firebase/firebase.py", line 72, in make_put_request
    response.raise_for_status()
  File "/Library/Python/2.7/site-packages/requests/models.py", line 683, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request

Hi,
I'm having the same issue. Is there any fix or workaround available?

Thanks!

Same error for me

Did any one managed to figure out why this is happening ?

Hi, same error, any idea of how make it work?

Mine works now, this is what I did:

    self.fbAuth = firebase.FirebaseAuthentication(<Firebase secret key>, None,
                extra={"provider": "custom", "uid": "abc", "pwd": <firebase secret>})
    self.fbRef = firebase.FirebaseApplication(<Firebase URL>, self.fbAuth)

Hi @ltejoles which sign-in providers did you enabled?

So, actually it works fine even like this, with all the sign-in provider disabled

authentication = FirebaseAuthentication('DATABASE_SECRET', None)
firebase = FirebaseApplication('URL', authentication)

I was erroneously using the "Web Api Key" under "General" tab, while the correct is the one in the "Database" tab.
Morever here is explicetely stated

In addition, the provided email and password information is totally
useless and they never appear in the ``auth`` variable at the server.

Hi @niqdev where can i get DATABASE_SECRET key, is there in firebase console?

Hi @ShreedharHM under Project Settings, the second tab.
The url should looks something like

https://console.firebase.google.com/project/YOUR_PROJECT_NAME/settings/database

After trying too many times, i decided to give up for "Ozgur" library.

You can simply use:
https://github.com/firebase/firebase-token-generator-python

Combined with "requests"
http://docs.python-requests.org/en/master/user/quickstart/

Here Are Code examples:

SECRET = "1234dfglkjetrjwiot24t24tkljw4tjklt4wt4" (your app secret in firebase)
auth_payload = {"uid": "1", "auth_data": "foo", "other_auth_data": "bar"}
options = { 'expires' : sys.maxint}
token = create_token(SECRET, auth_payload, options)

JSON_TOKEN = '.json?auth=' + token
URL = 'https://yourapp.firebaseio.com/' + ENV + '/yourDesiredPath' + JSON_TOKEN
BASEURL = 'https://yourapp.firebaseio.com/' + ENV + '/yourDesiredPath/'
GENERAL_COUNTER = 'https://yourapp.firebaseio.com/' + ENV + '/yourDesiredPath/someField' + JSON_TOKEN

resultPut = requests.put(GENERAL_COUNTER , data=json.dumps({'general':counter}))
resultDelete = requests.delete(BASEURL + key + JSON_TOKEN , data={}, headers={})

I have found this much easier to maintain and handle

This answer was useful for me, I finded the secret database key reading that answer.