Search code examples
djangodjango-modelsdjango-formsdjango-authenticationdjango-allauth

In django, how to sign in using Oauth, if signed up using CustomForm


My Django app has an option for login/register using CustomForm (inherited from the UserCreationForm) as well as Outh. Now the problem is if a user has already signed up using the CustomForm and if the next time he tries to log in using google Oauth then instead of logging in, google Oauth is redirecting to some other signup form (not created by me) which looks like:

But as the user is already registered, if he enters the same username/email here then it displays says username taken. So how can I resolve this issue? I mean I want the user to be able to login using Oauth even if he has signed up using the CustomForm, how can I implement that? Or even if I ask the user to fill this form to be able to use OAuth login, the problem is that his email/username are already present in the db, so he won't be able to sign up using this form.

Edit:

If that's difficult to implement then instead how can I just show a message when the user tries to login using oauth after signing up with the CustomForm, something like "You signed up using username rather than google account", rather than taking him to the socialaccount signup form?

My register function in views.py:

def register(request):
    if request.method == 'POST':
        
        form = CustomForm(request.POST or None)

        if form.is_valid():
            form.save()
            return redirect('login')

        else:
            return redirect('register')

    else:
        return render(request, 'accounts/register.html')

forms.py looks something like this:

class CustomForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ("username", "email")

Solution

  • You can use pre_social_login signal

    from allauth.exceptions import ImmediateHttpResponse
    from allauth.socialaccount.signals import pre_social_login
    from allauth.account.utils import perform_login
    from allauth.utils import get_user_model
    
    from django.dispatch import receiver
    from django.shortcuts import redirect
    from django.conf import settings
    
    @receiver(pre_social_login)
    def link_to_local_user(sender, request, sociallogin, **kwargs):
        email_address = sociallogin.account.extra_data['email']
        User = get_user_model()
        users = User.objects.filter(email=email_address)
        if users:
            perform_login(request, users[0], email_verification=settings.EMAIL_VERIFICATION)
            raise ImmediateHttpResponse(redirect(settings.LOGIN_REDIRECT_URL))
    

    See https://github.com/pennersr/django-allauth/issues/215