Google OAuth2 Signup in Django: 'Bad Request' Error on First Signup Attempt
I'm working on integrating Google OAuth2 login/signup with Django, but I'm encountering an issue during the first signup attempt.
The Flow:
New User Registration using Google.
The user clicks on the "Login with Google" button.
The user is redirected to the Google OAuth2 consent screen and logs in.
After successful Signup, Google redirects back to my app with a Bad Request -
"POST /api/v1/auth/google/ HTTP/1.1" 400 Bad Request
: this only happens first time the user tries to sign up, It returns a "Bad Request" error. The issue only occurs during the first signup, even though the user data is added to the database.If I try to login back with the same account using google now then i will be able to Login Successfully.
Relevant Code :
backend/api/urls.py :
path('auth/google/', GoogleLogin.as_view(), name='google_login')
backend/api/views.py :
from django.conf import settings
from django.http import HttpResponseRedirect
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from dj_rest_auth.registration.views import SocialLoginView
class GoogleLogin(SocialLoginView):
adapter_class = GoogleOAuth2Adapter
client_class = OAuth2Client
callback_uri = settings.REDIRECT_URI
def get(self, request):
return HttpResponseRedirect(redirect_to=settings.GOOGLE_AUTH_URL)
backend/api/adapter.py:
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from api.models import User
class CustomSocialAdapter(DefaultSocialAccountAdapter):
def pre_social_login(self, request, sociallogin):
# Ignore existing social accounts, just do this stuff for new ones
if sociallogin.is_existing:
return
# some social logins don't have an email address, e.g. facebook accounts
# with mobile numbers only, but allauth takes care of this case so just
# ignore it
if 'email' not in sociallogin.account.extra_data:
return
# check if given email address already exists.
# Note: __iexact is used to ignore cases
try:
email = sociallogin.account.extra_data['email'].lower()
existing_user = User.objects.get(email__iexact=email)
# if it does not, let allauth take care of this new social account
except User.DoesNotExist:
return
# if it does, connect this new social login to the existing user
sociallogin.connect(request, existing_user)
Any help would be greatly appreciated!
Adding the below block resolved the issue.
@csrf_exempt # This decorator exempts CSRF protection for the POST request
def post(self, request, *args, **kwargs):
return super().post(request, *args, **kwargs)