Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python django allauth社交帐户登录时连接到现有帐户_Python_Django_Django Allauth - Fatal编程技术网

Python django allauth社交帐户登录时连接到现有帐户

Python django allauth社交帐户登录时连接到现有帐户,python,django,django-allauth,Python,Django,Django Allauth,我有一个自定义用户模型,我使用django allauth进行社会注册和登录。 当用户使用已使用电子邮件注册的社交帐户登录时,我正在尝试将现有用户连接到新的社交帐户。我找到了这个 但当我尝试通过社交帐户登录时,我遇到了一个错误 RelatedObjectDoesNotExist at /accounts/facebook/login/callback/ SocialAccount has no user. 任何帮助都将不胜感激 我也意识到这方面的安全问题。但我还是想试试这个。我通过稍微更改适配

我有一个自定义用户模型,我使用django allauth进行社会注册和登录。 当用户使用已使用电子邮件注册的社交帐户登录时,我正在尝试将现有用户连接到新的社交帐户。我找到了这个

但当我尝试通过社交帐户登录时,我遇到了一个错误

RelatedObjectDoesNotExist at /accounts/facebook/login/callback/
SocialAccount has no user.
任何帮助都将不胜感激


我也意识到这方面的安全问题。但我还是想试试这个。

我通过稍微更改适配器的代码,成功地实现了这一点

适配器.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

如果子类化
DefaultSocialAccountAdapter
,我们必须在
settings.py
文件中指定
SOCIALACCOUNT\u ADAPTER='myapp.my\u ADAPTER.MySocialAccountAdapter'
,我找到了以下解决方案,该解决方案还可以检查电子邮件地址是否已验证

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)
如果您希望跳过验证步骤,我认为此解决方案还是更好一些:

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

它是用最新的
allauth
开箱即用实现的。您可以在模板中使用以下内容:

{%load socialaccount%}
URL如下所示:

/accounts/spotify/login/?process=connect

无需内部修改。

您是否阅读了有关自定义用户模型和django allauth的部分?客户类在哪里?客户类只是一个例子。我用django的AbstractBaseUser创建了一个自定义用户模型。好的。你能解释一下你是在allauth代码中做了这个更改还是创建了一个单独的类吗?这是django allauth发送的信号。您可以在这里查看文档。我在adapter.pyI中编写的自定义适配器中捕捉到了该事件,但它给出了AttributeError:“User”对象没有属性“backend”,这是完整的回溯:有没有任何可能的方法可以在pre_social_登录函数中获取从oauth提供程序请求的电子邮件和其他数据?我认为是
email\uuu isexact=verified\u email.email
当我发布问题时,连接功能已经存在。问题是我无法在登录时自动连接帐户。如果你有兴趣了解更多关于我所面临的问题,请过目。这很好地涵盖了这个问题,并帮助我找到了解决方案。
/accounts/spotify/login/?process=connect