Python backend migration from Gitkit to Firebase-Auth with python-jose to check token

On github, the useful google dev told me that

in order to create a user session, your python backend server only needs the JWT library to verify the Firebase Auth token (signature and audience) in the request and extract user information from the token payload.

I'm having trouble checking the token.

I am here; To start the migration, I did the following:

  • I added Firebase-Auth to the Android app, but I still have Gitkit in the app before Firebase-Auth. Now I have two login buttons, one of which fits into Firebase and one for the "almost obsolete" Gitkit.

  • On firebase.com, I imported the Google project into a new Firebase project, so the user database is the same. I already managed to use Firebase-Auth in an Android application, I can log in as a well-known user, and I can successfully get the token that I need for my backend server by calling mFirebaseAuth.getCurrentUser().getToken(false).getResult().getToken() . It contains the same user_id as the user_id token.

Now I am trying to replace the identity-toolkit-python-client library with python-jose . Since I do not currently send the Firebase token to the backend, but only the Gitkit token, I want to test this python-jose library on the Gitkit token.

On the backend, before calling GitKit.VerifyGitkitToken() I now print the results of jose.jwt.get_unverified_header() and jose.jwt.get_unverified_claims() to check if I can see what I expect. The results are good, I can view the contents of the Gitkit token as expected.

My problem is with validation. I cannot use jose.jwt.decode() to check, because I do not know which key I need to use .

jose.jwt.decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None)

I know that the algorithm from the header and the 'aud' field are also stored in the formula, if that is any help.

Returning to the comment of engineers

check Firebase Auth token (signature and audience)

How do I do this with the information I have? I assume that the audience is the โ€œaudโ€ field in the applications, but how to verify the signature?

As soon as I remove the Gitkit dependency on the server, I will continue the migration.

From what I saw, the GitKit library apparently makes an โ€œRPCโ€ request to the Google server for verification, but I could be wrong.

So what will be the key for checking the Gitkit token, as well as for checking the Firebase token?

+2
source share
1 answer

Keys can be obtained

for Firebase at https://www.googleapis.com/robot/v1/metadata/x509/ securetoken@system.gserviceaccount.com

and for Gitkit at https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys

Using the Googles oauth2client library makes checking very simple.

But if you want to use python-jose instead of oauth2client , then you first need to convert the PEM certificate to the RSA public key (update: this problem is fixed, since Firebase is now being processed by the library, it scrolls to the end in the GitHub link that precedes this comment. I donโ€™t know about Gitkit ) This public key is the key to use. And the audience should not be extracted from the JWT header , but hardcoded into the source code, where in Firebase the audience is the project identifier, and in Gitkit one of the OAuth 2.0 client identifiers that can be found in the "Credentials section of the Google Developer Console".

kid in the JWT header is used to select the appropriate certificate that will be used to obtain the key used to perform the verification.

  # firebase # target_audience = "firebase-project-id" # certificate_url = 'https://www.googleapis.com/robot/v1/metadata/x509/ securetoken@system.gserviceaccount.com ' # gitkit target_audience = "123456789-abcdef.apps.googleusercontent.com" # (from developer console, OAuth 2.0 client IDs) certificate_url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys' response = urllib.urlopen(certificate_url) certs = response.read() certs = json.loads(certs) print "CERTS", certs print '' print '' # -------------- verify via oauth2client from oauth2client import crypt crypt.MAX_TOKEN_LIFETIME_SECS = 30 * 86400 # according to https://github.com/google/identity-toolkit-python-client/blob/master/identitytoolkit/gitkitclient.py print "VALID TOKEN", crypt.verify_signed_jwt_with_certs(idtoken, certs, target_audience) print '' print '' # -------------- verify via python-jose from jose import jwt unverified_header = jwt.get_unverified_header(idtoken) print "UNVERIFIED HEADER", unverified_header print '' print '' unverified_claims = jwt.get_unverified_claims(idtoken) print "UNVERIFIED CLAIMS", unverified_claims print '' print '' from ssl import PEM_cert_to_DER_cert from Crypto.Util.asn1 import DerSequence pem = certs[unverified_header['kid']] der = PEM_cert_to_DER_cert(pem) cert = DerSequence() cert.decode(der) tbsCertificate = DerSequence() tbsCertificate.decode(cert[0]) rsa_public_key = tbsCertificate[6] print "VALID TOKEN", jwt.decode(idtoken, rsa_public_key, algorithms=unverified_header['alg'], audience=target_audience) 
+3
source

Source: https://habr.com/ru/post/1260436/


All Articles