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']
tooffline
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 toonline
.
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:
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.