Authalreadyassociated исключение в социальной аутентификации Django
после того, как я создаю пользователя, используя, скажем, Facebook(скажем, fbuser) или Google(googleuser). Если я создаю другого пользователя через обычного администратора django(normaluser) и снова пытаюсь войти в систему с помощью Facebook или Google, пока третий пользователь (normaluser) вошел в систему, он выдает исключение ошибки AuthAlreadyAssociated.
в идеале он должен выдавать ошибку под названием вы уже вошли в систему как normaluser пользователей.
или он должен выйти из обычного пользователя, и попробуйте связаться с учетная запись, которая уже связана с FB или Google, как в случае может быть.
Как реализовать одну из этих двух функций выше? Все советы приветствуются.
также, когда я пытаюсь настроить SOCIAL_AUTH_PIPELINE, невозможно войти в систему с помощью FB или Google, и это заставляет URL-адрес входа /учетные записи/login/
5 ответов
DSA не выходит из учетных записей (или флеш-сессий) на данный момент. AuthAlreadyAssociated
выделяет сценарий, в котором текущий пользователь не связан с текущей социальной учетной записью, пытающейся использоваться. Есть несколько решений, которые могут соответствовать вашему проекту:
определите подкласс
social_auth.middleware.SocialAuthExceptionMiddleware
и переопределить поведение по умолчанию (process_exception()
) для перенаправления или настройки предупреждения, которое вам нравится, так, как вы предпочитаете.добавить метод конвейера (замена
social_auth.backend.pipeline.social.social_auth_user
), который выходит из текущего пользователя вместо создания исключения.
мой подход к этой проблеме был немного другим, вместо того, чтобы решать это в конвейере, я убедился, что пользователь никогда не был передан в трубопровод в первую очередь. Таким образом, даже если social_auth.пользователь не соответствует зарегистрированному пользователю social_auth.пользователь будет зарегистрирован поверх текущего зарегистрированного пользователя.
Я думаю, что это так же просто, как переопределение complete
действие.
urls.py
url(r'^complete/(?P<backend>[^/]+)/$', 'account.views.complete', name='complete'),
account/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)
решение для людей, которым интересно, как переопределить конвейер social_user под python-social-auth версии 0.2.x
в вашем 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',
)
в social_user перекрытая:
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}
вы можете удалить прокомментированные строки, если хотите.
У меня такая же проблема. Я решил это, вставив ниже код в настройки
AUTHENTICATION_BACKENDS = (
'...',
'social_core.backends.facebook.FacebookOAuth2',
'...',
)
SOCIAL_AUTH_PIPELINE = (
'...',
'social_core.pipeline.user.user_details',
'...',
)
что я сделал:
определите класс, который наследуется от
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
исключение.