3

I implemented registration and login with django-allauth and django-rest-auth. I can successfully login with Facebook to the server with both allauth and rest-auth (web and mobile).

When I'm trying to login with FB account that its email already exists (someone already signed up with that email), it shows the signup form. However, when I'm trying doing the same using rest-auth, I get an error:

Internal Server Error: /rest-auth/facebook/

IntegrityError at /rest-auth/facebook/
duplicate key value violates unique constraint "auth_user_username_key"
DETAIL:  Key (username)=() already exists.

My Configuration:

ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = 'optional'
SOCIALACCOUNT_AUTO_SIGNUP = True
SOCIALACCOUNT_EMAIL_VERIFICATION = False
SOCIALACCOUNT_EMAIL_REQUIRED = True
SOCIALACCOUNT_QUERY_EMAIL = True
Rani
  • 6,424
  • 1
  • 23
  • 31
  • email already exists where? can you please clear it. – Umar Asghar Jan 10 '18 at 09:03
  • @UmarAsghar I meant that someone already signed up with that email (not using facebook login) – Rani Jan 11 '18 at 02:38
  • If someone has already signed up with that email, then it does make sense to use the same email again for login. Can I know your case why you feel its needed? – Umar Asghar Jan 11 '18 at 05:23
  • By the way, I have tested that case, first I registered from the website as a regular user. Then later I did login with social app, then it just log me in with my previous account without giving any error. so I need to know your case and flow. – Umar Asghar Jan 11 '18 at 09:34
  • There is a bug in rest-auth. I found a solution here https://github.com/Tivix/django-rest-auth/pull/382 – Rani Jan 11 '18 at 23:14
  • In addition, linking a social account to an existing account with the same email address can create a security hole, unless the email address is verified in both accounts. – Rani Jan 11 '18 at 23:15
  • You might be using outdated version. That can be the reason of it. – Umar Asghar Jan 12 '18 at 06:21
  • Why are you using allauth and rest-auth? – Evan Zamir Feb 05 '18 at 23:41
  • Yes, @EvanZamir – Rani Feb 06 '18 at 01:16
  • I upgrade to v.0.9.3 and now am getting an error "User is already registered with this e-mail address" when I try to do FB login after having already signed up for an email account. How to fix this? I opened up a github issue on the project but nobody has answered yet. https://github.com/Tivix/django-rest-auth/issues/409 – Evan Zamir Feb 06 '18 at 20:43
  • @UmarAsghar It does make sense to use FB Login, because you might have signed up a long time ago and not remember username or password you gave, and it's just easier to use the FB login. I do it all the time. In fact I do it on SO very often. – Evan Zamir Feb 06 '18 at 20:45
  • @EvanZamir I used it recently and i also do it very often. – Umar Asghar Feb 07 '18 at 04:40
  • @EvanZamir What would you like to do in that case? You can merge the accounts or ask for another email address? – Rani Feb 07 '18 at 18:02
  • I would merge the accounts. That is the whole point of having a FB login button. It’s for convenience. Asking a user to create an entirely new account with the same email makes no sense. Nor does asking for a new email. Have you ever seen an app with hat behavior? I sure haven’t. – Evan Zamir Feb 07 '18 at 18:56
  • @EvanZamir I'll post my code here to do that. Please note that if you decide to do that, then you should verify the user email address. Otherwise, you might create a security problem (another user can sign up with your email and get an access it once you connect your FB account) – Rani Feb 07 '18 at 23:01
  • Hmm that’s true. Thanks. – Evan Zamir Feb 08 '18 at 00:00

2 Answers2

4

I solved the issue by creating a social adapter that connects the existing account to the social account. Please make sure you're aware of the risks before using it - if the email address is not verified in one of the accounts a malicious user might take control of the account by signing up before the social signup (for example).

class MySocialAccountAdapter(DefaultSocialAccountAdapter):
    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
        except Exception as e:
            logger.exception('Social adapter failure - {}'.format(e))

You need to set the path to the adapter in the settings.py:

SOCIALACCOUNT_ADAPTER = 'path.to.MySocialAccountAdapter'
Rani
  • 6,424
  • 1
  • 23
  • 31
2

The latest version of django-rest-auth v0.9.3 now includes social connect views, which allow you to link existing account to a social account.

In order to use them you need to be authenticated via existing account, due to security issues outlined in the previous answer. More info in the docs: Additional Social Connect Views

Unique constraint 500 error is fixed as well.

Maxim Kukhtenkov
  • 734
  • 1
  • 7
  • 20