簡體   English   中英

Django 社交身份驗證中的 AuthAlreadyAssociated 異常

[英]AuthAlreadyAssociated Exception in Django Social Auth

在我使用 Facebook(假設 fbuser)或 Google(googleuser)創建用戶之后。 如果我通過普通 django 管理員(普通用戶)創建另一個用戶,並在第三個用戶(普通用戶)登錄時嘗試使用 Facebook 或 Google 再次登錄,則會引發錯誤異常 AuthAlreadyAssociated。

  1. 理想情況下,它應該拋出一個錯誤,稱您已經以用戶 normaluser 身份登錄。

  2. 或者它應該注銷普通用戶,並嘗試關聯已經與 FB 或 Google 關聯的帳戶,視情況而定。

如何實現上述兩個功能之一? 歡迎所有建議。

此外,當我嘗試自定義 SOCIAL_AUTH_PIPELINE 時,無法使用 FB 或 Google 登錄,並且會強制使用登錄 URL /accounts/login/

DSA 目前不會注銷帳戶(或刷新會話)。 AuthAlreadyAssociated突出顯示當前用戶未與嘗試使用的當前社交帳戶相關聯的場景。 有幾種解決方案可能適合您的項目:

  1. 定義social_auth.middleware.SocialAuthExceptionMiddleware的子類並覆蓋默認行為( process_exception() )以按照您喜歡的方式重定向或設置您喜歡的警告。

  2. 添加一個管道方法(替換social_auth.backend.pipeline.social.social_auth_user ),用於注銷當前用戶而不是引發異常。

對於想知道如何在 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}

如果需要,您可以刪除注釋行。

我解決這個問題的方法有點不同,我沒有在管道中解決這個問題,而是首先確保用戶從未被傳遞到管道中。 這樣,即使 social_auth.user 與登錄用戶不匹配,social_auth.user 也會在當前登錄用戶之上登錄。

我認為這就像覆蓋complete動作一樣簡單。

網址.py

url(r'^complete/(?P<backend>[^/]+)/$', 'account.views.complete', name='complete'),

帳戶/視圖.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)

我遇到了同樣的問題。 我通過在設置中插入以下代碼來解決它

AUTHENTICATION_BACKENDS = (
    '...',
    'social_core.backends.facebook.FacebookOAuth2',
    '...',
)
SOCIAL_AUTH_PIPELINE = (
    '...',
    'social_core.pipeline.user.user_details',
    '...',
)

我所做的是:

  1. 定義一個繼承自SocialAuthExceptionMiddleware的類

  2. 實現方法process_exception

  3. 將實現的類添加到settings.py上的MIDDLEWARE列表。

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異常時,我能夠處理控制流。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM