RealmTeam / django-rest-framework-social-oauth2

python-social-auth and oauth2 support for django-rest-framework
MIT License
1.06k stars 191 forks source link

Server side verification of google and facebook tokens #227

Open nicks101 opened 4 years ago

nicks101 commented 4 years ago

Google and Facebook both recommends to verify the tokens which are received from the client as follows:

https://developers.google.com/identity/sign-in/web/backend-auth

Does this package automatically verify the tokens or do we have to manually verify?

After you receive the ID token by HTTPS POST, you must verify the integrity of the token. To verify that the token is valid, ensure that the following criteria are satisfied:

  1. The ID token is properly signed by Google. Use Google's public keys (available in JWK or PEM format) to verify the token's signature. These keys are regularly rotated; examine the Cache-Control header in the response to determine when you should retrieve them again.
  2. The value of aud in the ID token is equal to one of your app's client IDs. This check is necessary to prevent ID tokens issued to a malicious app being used to access data about the same user on your app's backend server.
  3. The value of iss in the ID token is equal to accounts.google.com or https://accounts.google.com.
  4. The expiry time (exp) of the ID token has not passed.
  5. If you want to restrict access to only members of your G Suite domain, verify that the ID token has an hd claim that matches your G Suite domain name. Rather than writing your own code to perform these verification steps, we strongly recommend using a Google API client library for your platform, or a general-purpose JWT library. For development and debugging, you can call our tokeninfo validation endpoint.
from google.oauth2 import id_token
from google.auth.transport import requests

# (Receive token by HTTPS POST)
# ...

try:
    # Specify the CLIENT_ID of the app that accesses the backend:
    idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)

    # Or, if multiple clients access the backend server:
    # idinfo = id_token.verify_oauth2_token(token, requests.Request())
    # if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]:
    #     raise ValueError('Could not verify audience.')

    if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']:
        raise ValueError('Wrong issuer.')

    # If auth request is from a G Suite domain:
    # if idinfo['hd'] != GSUITE_DOMAIN_NAME:
    #     raise ValueError('Wrong hosted domain.')

    # ID token is valid. Get the user's Google Account ID from the decoded token.
    userid = idinfo['sub']
except ValueError:
    # Invalid token
    pass
wagnerdelima commented 4 years ago

Hi all.

My team and I are constantly using this framework and it seems it has died out there. I contacted the owner by email asking if he would add some of us as maintainers so we could continue to improve it. However we didn't get a response.

I am publishing the project under my profile and we are going to continue to invest time in it.

So I would like to gently ask you to contribute to this project on: https://github.com/wagnerdelima/drf-social-oauth2

Thank you for understanding.