Search code examples
django-allauthdjango-rest-auth

Allow user to register using django-all-auth even if the social account exists and then connect the two automatically


So, I have been able to connect social accounts (fb or google) to be connected to the local email account if already exists.

However, I also want the reverse functionality, i.e. I would like to allow user to sign up even if the (google or FB) social account exists. Currently it says:

{ A user is already registered with this email address }

I am using django-all-auth and django-rest-auth with Django 2.1


Solution

  • Yes, you can do that. You should be able to modify the password reset endpoint provided by django-rest-auth to set a password and then be able to login:

    from django.contrib.auth import get_user_model
    from django.contrib.auth.forms import PasswordResetForm as DjangoPasswordResetForm
    from rest_auth.serializers import (
        PasswordResetSerializer as RestAuthPasswordResetSerializer
    )
    from rest_auth.views import PasswordResetView as RestAuthPasswordResetView
    
    UserModel = get_user_model()
    
    
    class PasswordResetForm(DjangoPasswordResetForm):
        def get_users(self, email):
            """
            Given an email, return matching user(s) who should receive a reset.
            """
            active_users = UserModel._default_manager.filter(**{
                '%s__iexact' % UserModel.get_email_field_name(): email,
                'is_active': True,
            })
            return iter(active_users)
            # or (u for u in active_users if not u.has_usable_password())
    
    
    class PasswordResetSerializer(RestAuthPasswordResetSerializer):
        password_reset_form_class = PasswordResetForm
    
    
    class PasswordResetView(RestAuthPasswordResetView):
        serializer_class = PasswordResetSerializer
    

    You can add this view to your urls.py as general endpoint to reset passwords (remember to place it in front of the rest_auths' URLs) or as an additional endpoint to set passwords (see the commented line). Then you can add a note to your signup page that links to your page that serves your new endpoint.

    As an alternative, you could also add a field to your user settings page where users can set a password.

    You could also send an e-mail with a link via send_confirmation to set a password when a user tries to sign up and the e-mail exists already (or only in case this user has a social account). If you like I could add an example here how to do that.