【问题标题】:Python Social Auth duplicating e-mails for different usersPython Social Auth为不同用户复制电子邮件
【发布时间】:2017-03-30 12:19:17
【问题描述】:

在我的网站可以通过以下方式登录:

  • 用户名和密码
  • 电子邮件和密码
  • 谷歌身份验证 2
  • 脸书

我在哪里使用 django 用户内置系统和 python 社交身份验证。

问题:

假设我创建了以下帐户:

用户名:losimonassi 电子邮件:lorenzosimonassi@gmail.com

然后,当我尝试使用我的 gmail (lorenzosimonassi@gmail.com) 登录时,python social auth 会使用相同的电子邮件创建另一个用户。因此,当我尝试使用我的电子邮件登录时,身份验证系统会发现两封相似的电子邮件,这会引发错误。

我正在尝试找到一种方法,当用户尝试使用 gmail 登录时,他的电子邮件会根据数据库进行检查,如果它已经存在,则进程会通过重定向和警报消息停止(我认为可能是通过中间件制作)。

当然,对数据库的检查应该只检查其他后端用户和普通用户,以避免阻止他自己的登录。

我不想关联帐户。

settings.py

SOCIAL_AUTH_PIPELINE = (
    'social.pipeline.social_auth.social_details',
    'social.pipeline.social_auth.social_uid',
    'social.pipeline.social_auth.auth_allowed',
    'social.pipeline.social_auth.social_user',
    'social.pipeline.user.get_username',
    'social.pipeline.user.create_user',
    #'social.pipeline.social_auth.associate_user',
    #'social.pipeline.social_auth.load_extra_data',
    'social.pipeline.user.user_details'
)

admin image

【问题讨论】:

    标签: django django-authentication python-social-auth


    【解决方案1】:

    我遇到了你描述的情况。我解决它的方法:向社交身份验证管道添加自定义步骤:

    def check_email_exists(backend, details, uid, user=None, *args, **kwargs):
        email = details.get('email', '')
        provider = backend.name
    
        # check if social user exists to allow logging in (not sure if this is necessary)
        social = backend.strategy.storage.user.get_social_auth(provider, uid)
        # check if given email is in use
        exists = User.objects.filter(username=email).exists()
    
        # user is not logged in, social profile with given uid doesn't exist
        # and email is in use
        if not user and not social and exists:
            raise AuthException(backend)
    

    将您的可调用对象添加到管道中:

    SOCIAL_AUTH_PIPELINE = (
        'social.pipeline.social_auth.social_details',
        'social.pipeline.social_auth.social_uid',
        'social.pipeline.social_auth.auth_allowed',
        'social.pipeline.social_auth.social_user',
        'social.pipeline.user.get_username',
        'path.to.module.check_email_exists',  # move if appropriate
        'social.pipeline.user.create_user',
        'social.pipeline.user.user_details'
    )
    

    提高AuthException 会将用户重定向到您的settings.SOCIAL_AUTH_LOGIN_ERROR_URL。但是,如果这不是您想要的,还有另一种方法。 Python-social-auth 检查管道任何部分的返回值。如果返回值为None,则继续。如果它是dict,它将使用该字典更新 kwargs,以便稍后在管道中使用这些值。但是,如果返回值是HttpResponse,比如HttpResponseRedirect,它会将该响应返回给用户。因此,您可以这样做

    ,而不是提出AuthException
    return HttpResponseRedirect(reverse('desired-endpoint'))
    

    但是,请谨慎对待:文档并没有清楚地说明这一点,而且我很久以前就这样做了,所以我可能弄错了。

    【讨论】:

    • 嘿,谢谢!一个问题——你如何将错误返回给用户?基本上我想重定向到我的登录页面,但有一条消息说“对不起,电子邮件已在使用中”。
    • 有两种方法我可以在他飞行时想出。首先:django.contrib.messagesSocialAuthExceptionMiddleware。使用适当的消息子类SocialAuthException(覆盖__str__)并将其提升到管道中的某个位置。 SocialAuthExceptionMiddleware 将自动重定向到settings.LOGIN_ERROR_URL 并添加指定的消息。其次,正如我在答案中所描述的,您可以在管道中的任何位置返回HttpResponseRedirect,用户将被定向到该页面。
    【解决方案2】:

    您可以通过添加内置但默认情况下在管道中不活动的步骤来选择按用户的电子邮件地址关联用户。 请注意,只有当您确定社交服务提供商验证了电子邮件地址时,您才应该这样做。否则,我可以使用您的电子邮件注册社交提供商,登录您的网站并访问您网站上的用户。

    Python 社交认证文档以及如何通过电子邮件关联用户: https://python-social-auth-docs.readthedocs.io/en/latest/use_cases.html?highlight=associate%20user#associate-users-by-email

    从上面的链接:

    SOCIAL_AUTH_PIPELINE = (
        'social_core.pipeline.social_auth.social_details',
        'social_core.pipeline.social_auth.social_uid',
        'social_core.pipeline.social_auth.auth_allowed',
        'social_core.pipeline.social_auth.social_user',
        'social_core.pipeline.user.get_username',
        'social_core.pipeline.social_auth.associate_by_email',  # <--- enable this one
        'social_core.pipeline.user.create_user',
        'social_core.pipeline.social_auth.associate_user',
        'social_core.pipeline.social_auth.load_extra_data',
        'social_core.pipeline.user.user_details',
    )
    

    编辑:正如 Jack 在 cmets 中所指出的,管道步骤的顺序很重要。

    【讨论】:

    • 谢谢,重要的是要注意在 create_user 之前有关联的顺序。这就是让我着迷的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 2014-04-07
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多