AuthAlreadyAssociated Exception in Django Social Auth

会有一股神秘感。 提交于 2019-12-18 12:28:42

问题


After I create a user using say Facebook(let's say fbuser) or Google(googleuser). If I create another user through the normal django admin(normaluser), and try logging again using Facebook or Google while third user(normaluser) is logged in, it throws an error exception AuthAlreadyAssociated.

  1. Ideally it should throw an error called you are already logged in as user normaluser.

  2. Or it should log out normal user, and try associating with the account which is already associated with FB or Google, as the case may be.

How do I implement one of these two above features? All advice welcome.

Also when I try customizing SOCIAL_AUTH_PIPELINE, it is not possible to login with FB or Google, and it forces the login URL /accounts/login/


回答1:


DSA doesn't logout accounts (or flush sessions) at the moment. AuthAlreadyAssociated highlights the scenario where the current user is not associated to the current social account trying to be used. There are a couple solutions that might suite your project:

  1. Define a sub-class of social_auth.middleware.SocialAuthExceptionMiddleware and override the default behavior (process_exception()) to redirect or setup the warning you like in the way you prefer.

  2. Add a pipeline method (replacing social_auth.backend.pipeline.social.social_auth_user) that logouts the current user instead of raising an exception.




回答2:


My approach to this problem was a little different, instead of tackling this in the pipeline, I made sure that a user was never passed into the pipeline in the first place. This way, even if the social_auth.user does not match the logged in user, the social_auth.user will be logged in on top of the currently logged in user.

I think it's as easy as overriding the complete action.

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)



回答3:


Solution for people wondering how to override social_user pipeline under python-social-auth version 3+

In your 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',
)

In your overrided 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}

You can delete commented lines if you want.




回答4:


I got the same problem. I solved it by inserting below code in settings

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



回答5:


What I have done is:

  1. Define a class that inherits from SocialAuthExceptionMiddleware

  2. Implement the method process_exception,

  3. Add the implemented class to MIDDLEWARE list on settings.py.

In middleware.py, which should be in your apps's directory, i.e., same directory of your views.py file associated with your app, define the following class:

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"))

In settings.py, add the implemented class to the MIDDLEWARE list:

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",
]

This solved my problem, and I was able to handle the flow of control when the AuthAlreadyAssociated exception was raised.



来源:https://stackoverflow.com/questions/13018147/authalreadyassociated-exception-in-django-social-auth

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!