在我使用说Facebook(让我们说fbuser)或Google(googleuser)创建用户之后。如果我通过普通的django admin(normaluser)创建另一个用户,并在第三个用户(normaluser)登录时尝试使用Facebook或Google再次登录,则会抛出错误异常AuthAlreadyAssociated。
理想情况下,它应该抛出一个名为您已登录的错误 用户normaluser。
或者它应该注销普通用户,并尝试与之关联 已经与FB或Google关联的帐户,视情况而定 可能是。
如何实施上述两项功能之一?欢迎所有建议。
此外,当我尝试自定义SOCIAL_AUTH_PIPELINE时,无法使用FB或Google登录,并强制登录网址/ accounts / login /
答案 0 :(得分:11)
DSA目前不会注销帐户(或刷新会话)。 AuthAlreadyAssociated
突出显示当前用户未与尝试使用的当前社交帐户相关联的情况。有几种解决方案可能适合您的项目:
定义social_auth.middleware.SocialAuthExceptionMiddleware
的子类并覆盖默认行为(process_exception()
),以您喜欢的方式重定向或设置您喜欢的警告。
添加注销当前用户的管道方法(替换social_auth.backend.pipeline.social.social_auth_user
),而不是引发异常。
答案 1 :(得分:3)
我解决这个问题的方法略有不同,而不是在管道中解决这个问题,我确保用户从未首先进入管道。这样,即使social_auth.user与登录用户不匹配,social_auth.user也将登录在当前登录用户之上。
我认为这就像覆盖complete
行动一样容易。
urls.py
url(r'^complete/(?P<backend>[^/]+)/$', 'account.views.complete', name='complete'),
帐户/ views.py
from social.actions import do_complete
from social.apps.django_app.utils import strategy
from social.apps.django_app.views import _do_login
@csrf_exempt
@strategy('social:complete')
def complete(request, backend, *args, **kwargs):
"""Override this method so we can force user to be logged out."""
return do_complete(request.social_strategy, _do_login, user=None,
redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
答案 2 :(得分:3)
人们想知道如何在python-social-auth版本0.2.x下覆盖social_user管道的解决方案
在您的settings.py中:
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
'social.pipeline.social_auth.social_uid',
'social.pipeline.social_auth.auth_allowed',
# Path to your overrided method
# You can set any other valid path.
'myproject.apps.python-social-auth-overrided.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',
)
在您的首要社会用户:
from django.contrib.auth import logout
def social_user(backend, uid, user=None, *args, **kwargs):
'''OVERRIDED: It will logout the current user
instead of raise an exception '''
provider = backend.name
social = backend.strategy.storage.user.get_social_auth(provider, uid)
if social:
if user and social.user != user:
logout(backend.strategy.request)
#msg = 'This {0} account is already in use.'.format(provider)
#raise AuthAlreadyAssociated(backend, msg)
elif not user:
user = social.user
return {'social': social,
'user': user,
'is_new': user is None,
'new_association': False}
如果需要,您可以删除注释行。
答案 3 :(得分:0)
我遇到了同样的问题。我通过在设置中插入以下代码来解决它
AUTHENTICATION_BACKENDS = (
'...',
'social_core.backends.facebook.FacebookOAuth2',
'...',
)
SOCIAL_AUTH_PIPELINE = (
'...',
'social_core.pipeline.user.user_details',
'...',
)
答案 4 :(得分:0)
我所做的是:
定义一个继承自SocialAuthExceptionMiddleware
实现方法process_exception
,
将实现的类添加到 MIDDLEWARE
上的settings.py
列表中。
在应位于应用程序目录中的 middleware.py
中,即与应用程序关联的views.py
文件的同一目录中,定义以下类:
from django.shortcuts import redirect
from django.urls import reverse
from social_core.exceptions import AuthAlreadyAssociated
class FacebookAuthAlreadyAssociatedMiddleware(SocialAuthExceptionMiddleware):
"""Redirect users to desired-url when AuthAlreadyAssociated exception occurs."""
def process_exception(self, request, exception):
if isinstance(exception, AuthAlreadyAssociated):
if request.backend.name == "facebook":
message = "This facebook account is already in use."
if message in str(exception):
# Add logic if required
# User is redirected to any url you want
# in this case to "app_name:url_name"
return redirect(reverse("app_name:url_name"))
在 settings.py
中,将实现的类添加到MIDDLEWARE
列表中:
MIDDLEWARE = [
# Some Django middlewares
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"social_django.middleware.SocialAuthExceptionMiddleware",
# the middleware you just implemented
"app_name.middleware.FacebookAuthAlreadyAssociatedMiddleware",
]
这解决了我的问题,并且在引发AuthAlreadyAssociated
异常时,我能够处理控制流程。