Lor*_* SC 3 django django-authentication python-social-auth
在我的网站上,可以通过以下方式登录:
我在哪里使用系统内置的 django 用户和 python 社交身份验证。
问题:
假设我创建了以下帐户:
用户名:losimonassi 电子邮件:lorenzosimonassi@gmail.com
然后,当我尝试使用我的 gmail (lorenzosimonassi@gmail.com) 登录时,python social auth 会使用相同的电子邮件创建另一个用户。因此,当我尝试使用我的电子邮件登录时,身份验证系统会发现两个类似的电子邮件,这会引发错误。
我试图找到一种方法,当用户尝试使用 gmail 登录时,会根据数据库检查他的电子邮件,如果它已经存在,则通过重定向和警报消息停止进程(我认为可以通过中间件)。
但是当然对DB的检查应该只对其他后端用户和普通用户进行检查,以免阻塞自己的登录。
我不想关联帐户。
设置.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'
)
Run Code Online (Sandbox Code Playgroud)
您可以选择通过添加内置的电子邮件地址来关联用户,但默认情况下不是管道中的活动步骤。请注意,只有当您确定社交提供商会验证电子邮件地址时,才应执行此操作。否则,我可以使用您的电子邮件注册社交提供商,登录您的网站并访问您网站上的用户。
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',
)
Run Code Online (Sandbox Code Playgroud)
编辑:正如 Jack 在评论中所指出的,管道步骤的顺序很重要。
你描述的情况我也遇到过。我解决它的方式:向社交身份验证管道添加自定义步骤:
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)
Run Code Online (Sandbox Code Playgroud)
将您的可调用对象添加到管道中:
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'
)
Run Code Online (Sandbox Code Playgroud)
Raising AuthException will redirect user to your settings.SOCIAL_AUTH_LOGIN_ERROR_URL. However, if that is not what you want, there also is another approach. Python-social-auth checks return value of any part of your pipeline. If return value is None, it just proceeds. If it is a dict, it will update kwargs using that dictionary so that the values are available later in the pipeline. However, if the return value is HttpResponse, say, HttpResponseRedirect, it will return that response to the user. So, instead of raising an AuthException, you can do
return HttpResponseRedirect(reverse('desired-endpoint'))
Run Code Online (Sandbox Code Playgroud)
However, do take that with a grain of salt: the docs don't state this clearly and I have done this quite some time ago, so I might be mistaken.
| 归档时间: |
|
| 查看次数: |
1964 次 |
| 最近记录: |