django-allauth social account connect to existing account on login

后端 未结 3 1555
无人及你
无人及你 2020-12-13 16:31

I have a custom user model and I am using django-allauth for social registration and login. I am trying to connect existing user to new social account when a user login usi

相关标签:
3条回答
  • 2020-12-13 16:39

    I found the following solution here that also checks that the email addresses are verified.

    from allauth.account.models import EmailAddress
    
    def pre_social_login(self, request, sociallogin):
    
            # social account already exists, so this is just a login
            if sociallogin.is_existing:
                return
    
            # some social logins don't have an email address
            if not sociallogin.email_addresses:
                return
    
            # find the first verified email that we get from this sociallogin
            verified_email = None
            for email in sociallogin.email_addresses:
                if email.verified:
                    verified_email = email
                    break
    
            # no verified emails found, nothing more to do
            if not verified_email:
                return
    
            # check if given email address already exists as a verified email on
            # an existing user's account
            try:
                existing_email = EmailAddress.objects.get(email__iexact=email.email, verified=True)
            except EmailAddress.DoesNotExist:
                return
    
            # if it does, connect this new social login to the existing user
            sociallogin.connect(request, existing_email.user)
    

    if you prefer to skip the verification step, I think this solution is still a bit better:

    def pre_social_login(self, request, sociallogin):
    
        user = sociallogin.user
        if user.id:
            return
        if not user.email:
            return
    
        try:
            user = User.objects.get(email=user.email)  # if user exists, connect the account to the existing account and login
            sociallogin.connect(request, user)
        except User.DoesNotExist:
            pass
    
    0 讨论(0)
  • 2020-12-13 16:51

    It's implemented out of the box with the latest allauth. You can use the following in your templates:

    {% load socialaccount %}
    <a href="{% provider_login_url "spotify" process="connect" %}">connect spotify account</a>
    

    The URL is the following:

    /accounts/spotify/login/?process=connect
    

    No internal modifications needed.

    0 讨论(0)
  • 2020-12-13 16:53

    I managed to get this working by changing the code for adapter a little bit.

    adapter.py

    from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
    
    class MySocialAccountAdapter(DefaultSocialAccountAdapter):
        def pre_social_login(self, request, sociallogin): 
            user = sociallogin.user
            if user.id:  
                return          
            try:
                customer = Customer.objects.get(email=user.email)  # if user exists, connect the account to the existing account and login
                sociallogin.state['process'] = 'connect'                
                perform_login(request, customer, 'none')
            except Customer.DoesNotExist:
                pass
    

    If subclassing DefaultSocialAccountAdapter, we have to specify SOCIALACCOUNT_ADAPTER = 'myapp.my_adapter.MySocialAccountAdapter' in settings.py file

    0 讨论(0)
提交回复
热议问题