AsifArmanRahman / firebase-rest-api

A simple python wrapper for Google's Firebase REST API's.
https://firebase-rest-api.readthedocs.io
MIT License
60 stars 14 forks source link

[Feature]: Verify id tokens #9

Closed Lxstr closed 1 year ago

Lxstr commented 1 year ago

Is your proposal related to a problem?

Hi Asif, would be great to be able to use the function:
decoded_token = auth.verify_id_token(id_token)

Describe the solution you'd like.

Be able to acces the decoded token claims:
{
  'iss': 'https://securetoken.google.com/project-id',
  'aud': 'project-id',
  'auth_time': 1622574389,
  'user_id': 'abcdefgh1234567890',
  'sub': 'abcdefgh1234567890',
  'iat': 1622574390,
  'exp': 1622577990,
  'email': 'user@example.com',
  'email_verified': True,
  'firebase': {
    'identities': {
      'email': ['user@example.com']
    },
    'sign_in_provider': 'password'
  }
}

Describe alternatives you've considered.

https://firebase.google.com/docs/auth/admin/verify-id-tokens#web

Additional context.

Trying to get the expiry timestamp in order to check if i need to refresh the users idToken. Then I would set up requirement to pass idToken as extra security layer

github-actions[bot] commented 1 year ago

Hello @Lxstr , thank you for submitting an issue! A project committer will shortly review the issue.

AsifArmanRahman commented 1 year ago

Hey @Lxstr.

I actually need your opinion on how this should be done. As mentioned here Verify ID tokens using a third-party JWT library, should I procced with all the checks to verify it? Or do it simply by retrieving the public key for the kid in the headers and verify it using the retrieved public key.

Lxstr commented 1 year ago

I wasn't sure if we had to actually verify it, I thought could just call the api and use the response, but I really have not much of an idea of what is correct here. I am only coming from perspective of a serverside app.

I managed to wrangle something from AI after some back an forth, could this be an option?


url = f"https://identitytoolkit.googleapis.com/v1/accounts:lookup?key={firebase_project_id}"

payload = {
    "idToken": id_token,
    "returnSecureToken": True
}

response = requests.post(url, data=json.dumps(payload))

if response.ok:
    user_info = response.json()["users"][0]
    decoded_token = base64.urlsafe_b64decode(id_token.split(".")[1] + "==").decode("utf-8")
    token_info = json.loads(decoded_token)
else:
    error_message = response.json()["error"]["message"]
    print(f"Error verifying ID token: {error_message}")
AsifArmanRahman commented 1 year ago

I haven't tested it yet, but by the looks of it, it seems like the v1 endpoint for Get Account Info which is used in get_account_info, and it doesn't return decoded claims stored in the id_token

Lxstr commented 1 year ago

Awesome, thanks for your hard work! Hopefully, this will be handy additional feature for people using the token passing feature. Although, in hindsight I'm not sure if using this as an extra layer in my case (server side) is truly needed so I'll maybe write about it and see if there's some feedback.