首页 文章

Python Social Auth为不同用户复制电子邮件

提问于
浏览
0

在我的网站上可以登录:

  • 用户名和密码

  • 电子邮件和密码

  • google auth 2

  • 脸书

我在哪里使用django用户内置系统和python社交认证 .

问题:

假设我创建了以下帐户:

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

然后,当我尝试使用我的gmail(lorenzosimonassi@gmail.com)登录时,python social auth会使用相同的电子邮件创建另一个用户 . 因此,当我尝试使用我的电子邮件登录时,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

2 回答

  • 0

    我遇到过你描述的情况 . 方式我解决了它:向社交auth管道添加自定义步骤:

    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)
    

    将您的callable添加到管道:

    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'))
    

    但是,确实带着一点点盐:文档没有清楚地说明这一点,而且我很久以前就这样做了,所以我可能会弄错 .

  • 1

    您可以选择通过添加内置但默认情况下管道中未激活的步骤来按用户的电子邮件地址关联用户 . 请注意,只有在您确定社交提供商验证电子邮件地址时才应执行此操作 . 否则,我可以使用您的电子邮件注册社交提供商,登录您的网站并访问您网站上的用户 .

    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',
    )
    

相关问题