Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decode Firebase JWT token in Python

I have added Firebase to allow clients to authenticate directly from the web app client (browser). I am using the firebase-web JS package and it works great. I can see in my browser that I receive a user object with information about the user, including an idToken.

I need to then authenticate this user on my server backend, which is python django. In the Firebase docs I found a how-to for exactly what I am trying to do, which is to verify the id token.

Since they don't have the supported Firebase sdk for python, I need to use a third party solution. I have come to the python-jose package after finding it listed on the jwt.io site. The example looks simple enough:

jwt.decode(token, 'secret', algorithms=['RS256'])

This is my first time using JWT. I don't know what to use for the 'secret'. I tried pasting my id token as token, and the web API key from the Firebase console for secret, but got this error:

jose.exceptions.JWKError: RSA key format is not supported

I also tried the JWT debugger, which seems to be reading most of my id token correctly, but the signature verification is looking for a public and/or a private keys, which like the 'secret' are escaping me.

enter image description here

I am really at a loss for how to find this secret, and how to verify the JWT id token in general. The information on the Firebase docs (third-party section) is:

Finally, ensure that the ID token was signed by the private key corresponding to the token's kid claim. Grab the public key from https://www.googleapis.com/robot/v1/metadata/x509/[email protected] and use a JWT library to verify the signature. Use the value of max-age in the Cache-Control header of the response from that endpoint to know when to refresh the public keys.

I have tried pasting the whole json blob from that googleapis url into the JWT debugger, but still getting an "invalid signature" alert. I don't understand how to use that public key.

Should python-jose work for this approach? If so, what should I use for the secret? If not, can someone point me in the right direction?

Thanks.

like image 920
jeffery_the_wind Avatar asked Nov 28 '16 08:11

jeffery_the_wind


People also ask

How do you decrypt a JWT token in Python?

The library PyJWT has an option to decode a JWT without verification: Without this option, the decode function does not only decode the token but also verifies the signature and you would have to provide the matching key.

How do I decode a firebase token?

The Firebase Admin SDK has a built-in method for verifying and decoding ID tokens. If the provided ID token has the correct format, is not expired, and is properly signed, the method returns the decoded ID token. You can grab the uid of the user or device from the decoded token.

How do I get the JWT token from Firebase authentication?

To achieve this, you must create a server endpoint that accepts sign-in credentials—such as a username and password—and, if the credentials are valid, returns a custom JWT. The custom JWT returned from your server can then be used by a client device to authenticate with Firebase (iOS+, Android, web).


1 Answers

I finally found the answer I was looking for in this post: Migrating Python backend from Gitkit to to Firebase-Auth with python-jose for token verification

Since the time of the post there have been updates made to the python-jose package, which gives better support for firebase id tokens. Here is some working code ( jose version 1.3.1 ) on how to use python to decode the firebase id token:

import urllib, json
from jose import jwt

idtoken = "<id token passed to server from firebase auth>"

target_audience = "<firebase app id>"

certificate_url = 'https://www.googleapis.com/robot/v1/metadata/x509/[email protected]'

response = urllib.urlopen(certificate_url)
certs = response.read()
certs = json.loads(certs)

#will throw error if not valid
user = jwt.decode(idtoken, certs, algorithms='RS256', audience=target_audience)
print user
like image 199
jeffery_the_wind Avatar answered Sep 21 '22 17:09

jeffery_the_wind