2015-03-06 13 views
7

Ho un modello utente personalizzato e sto utilizzando django-allauth per la registrazione e l'accesso social. Sto cercando di connettere l'utente esistente a un nuovo account social quando un utente effettua l'accesso utilizzando un account social che ha già effettuato la registrazione tramite e-mail. Ho trovato questo link.account social di django-allauth connettersi all'account esistente all'accesso

def pre_social_login(self, request, sociallogin): 
    user = sociallogin.account.user 
    if user.id: 
     return 
    try: 
     customer = Customer.objects.get(email=user.email) 
    except Customer.DoesNotExist: 
     pass 
    else: 
     perform_login(request, customer, 'none') 

Ma sto ricevendo un errore quando tento di accedere tramite account social.

RelatedObjectDoesNotExist at /accounts/facebook/login/callback/ 
SocialAccount has no user. 

Qualsiasi aiuto sarà apprezzato.

Anche io sono a conoscenza del problema di sicurezza in questo. Ma voglio ancora provarlo.

+0

Hai letto il paragrafo riguardante modelli utente personalizzati e django-allauth? http://django-allauth.readthedocs.org/en/latest/advanced.html#custom-user-models – petkostas

risposta

15

Sono riuscito a farlo funzionare cambiando leggermente il codice per l'adattatore.

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 

Se sottoclassi DefaultSocialAccountAdapter, dobbiamo specificare SOCIALACCOUNT_ADAPTER = 'myapp.my_adapter.MySocialAccountAdapter' in settings.py file di

+0

Dov'è la classe Cliente ?? –

+1

La classe cliente è solo un esempio. Ho creato un modello utente personalizzato con AbstractBaseUser di django. – anupsabraham

+1

Okay. Puoi anche spiegare se hai fatto questo cambiamento nel codice di verità o hai fatto una lezione separata? –

0

ho trovato la seguente soluzione here che controlla anche che gli indirizzi e-mail vengono verificati.

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) 

se si preferisce saltare il passaggio di verifica, penso che questa soluzione è ancora un po 'meglio:

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