16

在我使用 Facebook(比如说 fbuser)或 Google(googleuser)创建用户之后。如果我通过普通 django 管理员(普通用户)创建另一个用户,并在第三个用户(普通用户)登录时尝试使用 Facebook 或 Google 再次登录,则会引发错误异常 AuthAlreadyAssociated。

  1. 理想情况下,它应该抛出一个错误,称为您已经以用户 normaluser 身份登录。

  2. 或者它应该注销普通用户,并尝试与已经与 FB 或 Google 关联的帐户关联,视情况而定。

如何实现上述两个功能之一?欢迎所有建议。

此外,当我尝试自定义 SOCIAL_AUTH_PIPELINE 时,无法使用 FB 或 Google 登录,它会强制登录 URL /accounts/login/

4

5 回答 5

16

DSA 目前不会注销帐户(或刷新会话)。AuthAlreadyAssociated突出显示当前用户未关联到当前尝试使用的社交帐户的场景。有几个解决方案可能适合您的项目:

  1. 定义一个子类social_auth.middleware.SocialAuthExceptionMiddleware并覆盖默认行为 ( process_exception()) 以按照您喜欢的方式重定向或设置您喜欢的警告。

  2. social_auth.backend.pipeline.social.social_auth_user添加注销当前用户而不是引发异常的管道方法(替换)。

于 2012-10-23T14:36:39.430 回答
5

想知道如何在 python-social-auth 版本 3+ 下覆盖 social_user 管道的人的解决方案

在您的 settings.py 中:

SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.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_core.pipeline.user.get_username',
    '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',
)

在您覆盖的 social_user 中

from django.contrib.auth import logout

def social_user(backend, uid, user=None, *args, **kwargs):
    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)
        elif not user:
            user = social.user
    return {'social': social,
            'user': user,
            'is_new': user is None,
            'new_association': False}

如果需要,您可以删除注释行。

于 2014-12-05T18:09:51.040 回答
3

我解决这个问题的方法有点不同,我没有在管道中解决这个问题,而是首先确保用户永远不会被传递到管道中。这样,即使 social_auth.user 与登录用户不匹配,social_auth.user 也会在当前登录用户之上登录。

我认为这就像覆盖complete动作一样容易。

网址.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)
于 2014-08-08T19:33:17.133 回答
0

我所做的是:

  1. 定义一个继承自的类SocialAuthExceptionMiddleware

  2. 实现方法process_exception

  3. 将实现的类添加MIDDLEWAREsettings.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这解决了我的问题,并且在引发异常时我能够处理控制流。

于 2018-07-27T21:28:17.240 回答
0

我遇到了同样的问题。我通过在设置中插入以下代码来解决它

AUTHENTICATION_BACKENDS = (
    '...',
    'social_core.backends.facebook.FacebookOAuth2',
    '...',
)
SOCIAL_AUTH_PIPELINE = (
    '...',
    'social_core.pipeline.user.user_details',
    '...',
)
于 2017-03-14T13:35:43.613 回答