2012-10-22 35 views
9

Po utworzeniu użytkownika za pomocą powiedzmy Facebook (powiedzmy fbuser) lub Google (googleuser). Jeśli utworzę innego użytkownika za pośrednictwem normalnego administratora django (normaluser) i spróbuję zalogować się ponownie za pomocą Facebooka lub Google, gdy zalogowany jest trzeci użytkownik (normaluser), zostanie zgłoszony wyjątek błędu AuthAlreadyAssociated.AuthAlreadyAssocjowany wyjątek w Django Social Auth

  1. Idealnie powinno rzucać się błąd o nazwie jesteś już zalogowany jako użytkownika normaluser.

  2. Może też wylogować zwykłego użytkownika i spróbować powiązać go z kontem , które jest już powiązane z FB lub Google, ponieważ może to być przypadek .

Jak mogę wdrożyć jedną z tych dwóch funkcji? Wszystkie rady są mile widziane.

także przy próbie dostosowywania SOCIAL_AUTH_PIPELINE, to nie jest możliwe, aby zalogować się z FB i Google, a to wymusza logowanie URL/konta/login/

Odpowiedz

9

DSA nie wylogowania kont (lub sesje spłukiwania) przy za chwilę. AuthAlreadyAssociated podświetla scenariusz, w którym bieżący użytkownik nie jest powiązany z bieżącym kontem społecznościowym, który próbuje zostać użyty. Istnieje kilka rozwiązań, które mogłyby swoich projekt:

  1. Zdefiniuj podklasę social_auth.middleware.SocialAuthExceptionMiddleware i nadpisać domyślne zachowanie (process_exception()), aby przekierować lub konfiguracji ostrzeżenie chcesz w sposób wolisz.

  2. Dodaj metodę rurociągu (zastępując social_auth.backend.pipeline.social.social_auth_user), która wylogowuje bieżącego użytkownika, zamiast zgłaszać wyjątek.

+0

Próbowałem zrobić opcję nr 2, ale nie udało się. Pomyślnie loguje użytkownika, ale nie z powrotem jako nowy użytkownik social.user. wymianie. msg = 'Ten {0} konto jest już w użyciu' Format (dostawca) podnieść AuthAlreadyAssociated (strategy.backend, MSG) z: wylogowania (kwargs.get ('Wniosek')) użytkownik = social.user – nwilson5

+0

@omab: Na pythonie, social auth za pomocą Django, w jaki sposób powinienem bezproblemowo w tym samym żądaniu wylogować bieżącego użytkownika i skonfigurować sesję dla drugiego użytkownika korzystającego z wymiany potoku social_user? – jacob

+0

@omab: W social.actions.do_complete, is_authenticated ustawia się na początku na podstawie istniejącego użytkownika ("użytkownik A"). Ale jeśli wyloguję "użytkownika A" w potoku i zwrócę "użytkownika B", to do_complete nie zaloguje się "użytkownik B", ponieważ jest on_authenticated został już ustawiony True. Czy do_complete należy ponownie ocenić użytkownika sesji po zakończeniu potoku, aby określić, czy zalogować się "użytkownik B"? – jacob

3

Moje podejście do tego problemu było trochę inaczej, zamiast walki z tym w rurociągu, zrobiłem pewien, że użytkownik nigdy nie został przekazany do rurociągu w pierwszej kolejności. W ten sposób, nawet jeśli plik social_auth.user nie pasuje do zalogowanego użytkownika, social_auth.user będzie zalogowany na górze aktualnie zalogowanego użytkownika.

Myślę, że to jest tak proste, jak nadpisanie akcji complete.

urls.py

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

konto/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) 
+1

Gdzieś po jakimś czasie moje wcześniejsze rozwiązanie nie działa poprawnie, być może z najnowszym pythonem społecznościowym. W każdym razie twoje rozwiązanie działa poprawnie i jest z pewnością prostsze niż moje. Usunąłem moje z tego pytania. Dzięki. – jacob

+0

To nie działa (tak jak jest), ponieważ oryginalny widok "kompletny" zmienił się nieznacznie. Musiałem zanurkować w źródle i nieco go poprawić, aby dopasować się do zmian, ale strategia jest solidna, nadpisać parametr użytkownika bezwarunkowo przekazując Brak. –

+0

najnowszą wersję roboczą (wersja 0.3.x) kompletnej funkcji dla mnie https://maketips.net/tip/450/fix-authalreadyassociated-at-complete-this-account-is-already-in-use – user3479125

2

rozwiązanie dla osób, zastanawiając się, jak zastąpić rurociągu social_user pod wersja python-społeczno-auth 0.2.x

W ustawieniach .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', 
) 

W swojej overrided 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} 

Można delete skomentował linii, jeśli chcesz.

+2

Twoje podejście wylogowuje bieżącego użytkownika. Ale nie loguje się do nowo uwierzytelnionego użytkownika. Jakaś pomoc? – rishabsaraf93

0

Mam ten sam problem. Rozwiązałem go, wstawiając poniżej kod w ustawieniach

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