I'm trying to implement Google authentication in django with allauth and rest-auth. After many hours of research, none of the solutions I found worked in my project.
I based my code on a github issue: https://github.com/Tivix/django-rest-auth/issues/403
And an article: https://medium.com/@gonzafirewall/google-oauth2-and-django-rest-auth-92b0d8f70575
I have also created a Social Application object with Google client id and client secret
Authorized JavaScript origins: http://localhost:8000 Authorized redirect URIs: http://localhost:8000/api/v1/users/login/google/callback/
providers.py:
from allauth.socialaccount.providers.google.provider import GoogleProvider
class GoogleProviderMod(GoogleProvider):
def extract_uid(self, data):
return str(data['sub'])
adapters.py:
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from google.auth.transport import requests
from google.oauth2 import id_token
from myproj.users.providers import GoogleProviderMod
class GoogleOAuth2AdapterIdToken(GoogleOAuth2Adapter):
provider_id = GoogleProviderMod.id
def complete_login(self, request, app, token, **kwargs):
idinfo = id_token.verify_oauth2_token(token.token, requests.Request(), app.client_id)
if idinfo["iss"] not in ["accounts.google.com", "https://accounts.google.com"]:
raise ValueError("Wrong issuer.")
extra_data = idinfo
login = self.get_provider().sociallogin_from_response(request, extra_data)
return login
views.py:
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from rest_auth.registration.serializers import SocialLoginSerializer
from rest_auth.registration.views import SocialLoginView
from myproj.users.adapters import GoogleOAuth2AdapterIdToken
class GoogleLoginView(SocialLoginView):
adapter_class = GoogleOAuth2AdapterIdToken
callback_url = "http://localhost:8000/api/v1/users/login/google/callback/"
client_class = OAuth2Client
serializer_class = SocialLoginSerializer
urls.py:
from allauth.socialaccount.providers.oauth2.views import OAuth2CallbackView
from django.urls import path
from myproj.users.adapters import GoogleOAuth2AdapterIdToken
from myproj.users.views import GoogleLoginView
app_name = "users"
urlpatterns = [
path(
"login/google/",
GoogleLoginView.as_view(),
name="google_login"
),
path(
"login/google/callback/",
OAuth2CallbackView.adapter_view(GoogleOAuth2AdapterIdToken),
name="google_callback"
),
]
settings.py:
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend",
]
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "http"
When I passing ID Token (returned from Google 'sign in' button) as code parameter on login page, the error occurring:
allauth.socialaccount.providers.oauth2.client.OAuth2Error: Error retrieving access token: b'{\n "error": "invalid_grant",\n "error_description": "Malformed auth code."\n}'
Response code is 400.
Actually, even if I passing some random text to the code, the error is the same.
Thanks for help!
And these are all provided by drf(django rest framework) and other than these like oauth, oauth2 based authentication are provided by the efforts of the community with help of other python packages. And they can be easily used in the production environment.
Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.
I also integrate djangorestframework + django-allauth + django-rest-auth + djangorestframework-jwt. But, I just implement for Signin with Google, so user can't register manual.
Here is my code:
views.py
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from rest_auth.registration.views import SocialLoginView
class GoogleLogin(SocialLoginView):
adapter_class = GoogleOAuth2Adapter
client_class = OAuth2Client
urls.py
...
path('auth/google', GoogleLogin.as_view(), name='google_login'),
...
settings.py
INSTALLED_APPS = [
...
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
...
]
SITE_ID = 1
REST_USE_JWT = True # this is for djangorestframework-jwt
[UPDATE]
To use code
params on SocialLoginView endpoint:
https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=<https_callback>&prompt=consent&response_type=code&client_id=<cliend_id>&scope=email&access_type=offline
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With