django-rest-auth - Facebook 社交登录引发现有电子邮件的唯一约束违规

Ran*_*ani 3 django facebook-login django-rest-framework django-allauth django-rest-auth

我使用 django-allauth 和 django-rest-auth 实现了注册和登录。我可以使用allauth 和rest-auth(网络和移动设备)成功使用Facebook 登录服务器。

当我尝试使用 FB 帐户登录时,其电子邮件已存在(有人已使用该电子邮件注册),它会显示注册表单。但是,当我尝试使用 Rest-auth 执行相同操作时,出现错误:

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.
Run Code Online (Sandbox Code Playgroud)

我的配置:

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
Run Code Online (Sandbox Code Playgroud)

Ran*_*ani 5

我通过创建一个将现有帐户连接到社交帐户的社交适配器解决了这个问题。请确保您在使用前了解风险 - 如果某个帐户中的电子邮件地址未经过验证,恶意用户可能会通过在社交注册之前注册来控制该帐户(例如)。

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))
Run Code Online (Sandbox Code Playgroud)

您需要在settings.py中设置适配器的路径:

SOCIALACCOUNT_ADAPTER = 'path.to.MySocialAccountAdapter'
Run Code Online (Sandbox Code Playgroud)