How to use django-allauth for Google API?

How is django-allauth implemented to obtain authorization using Oauth2 for a Google API (in my case the Gmail API)? Additionally, I am looking to implement this separately from using django-allauth to have users log in with Google, so I would need to store it separately, and also call it in a view.

Thanks!

I'm assuming you have already followed this document and this, and made all the necessary primary settings.

Then you can use django-allauth to set up authentication via Google, with tokens saved. Specify the required parameters for gmail scope. Then use these tokens to work with GmailAPI.

First you need to set some settings, this is described in this document (SOCIALACCOUNT_STORE_TOKENS constant). Something like this:

#  settings.py
SOCIALACCOUNT_STORE_TOKENS = True
SOCIALACCOUNT_EMAIL_AUTHENTICATION = True
SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True

Also configure “access_type”: “offline”, in the google provider settings, as described here:

You must set AUTH_PARAMS['access_type'] to offline in order to receive a refresh token on first login and on reauthentication requests (which is needed to refresh authentication tokens in the background, without involving the user’s browser). When unspecified, Google defaults to online.

Now, after the user logs in to your system through google account, a database entry will be created with his access_token and refresh_token (token_secret in db_table). You can check this in the admin interface in this table:

admin

To use GmailAPI, you need the google user ID and its access_token, this can be found like this:

def get_user_google_tokens(request: HttpRequest, limit: int = 1) -> list[dict]:
    from allauth.socialaccount.models import SocialToken
    from django.db import models

    user_google_tokens = list(
        SocialToken.objects
        .filter(account__provider='google', account__user_id=request.user.pk)
        .annotate(google_user_id=models.F('account__uid'))
        .order_by('-expires_at')
        .values('token', 'token_secret', 'expires_at', 'google_user_id')[:limit]
    )
    print(user_google_tokens)
    #  [
    #   {'token': '...', 
    #    'token_secret': '...', 
    #    'expires_at': datetime.datetime(2025, 2, 7, 16, 38, 16, 611588, tzinfo=datetime.timezone.utc), 
    #    'google_user_id': '...'}
    #  ]
    return user_google_tokens

Note that access_token has a short validity of one hour, by default. You can read more about it here. When your access_token expires in time, you will need to refresh it using refresh_token (token_secret), and write new access_token to the database by modifying an existing entry. Here's an example of how to refresh. Also note that sometimes you will not be able to refresh tokens using refresh_token.

Here is an example of a request to update a token using Postman. But you will probably use some library for http requests for python. Or some off-the-shelf client, for that matter. django-allauth doesn't seem to be able to update tokens, but I don't know for sure, I haven't checked that.

postman

Вернуться на верх