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)
Back to Top