2012-10-22 51 views
9

我使用说Facebook(让我们说fbuser)或谷歌(谷歌用户)创建一个用户。如果我通过普通的django admin(normaluser)创建另一个用户,并在第三个用户(normaluser)登录时使用Facebook或Google再次尝试登录,则会引发错误异常AuthAlreadyAssociated。在Django社交认证中AuthAlreadyAssociated例外

  1. 理想情况下,应该抛出叫您已经登录的用户 的normaluser错误。

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

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

而且当我尝试定制SOCIAL_AUTH_PIPELINE,这是不可能的FB或谷歌登录,并迫使登录网址/帐号/登录/

回答

9

DSA不注销的账户(或刷新会话)时刻。 AuthAlreadyAssociated突出显示当前用户未与试图使用的当前社交帐户关联的情况。有迹象表明,可能适合你的项目一对夫妇的解决方案:

  1. 定义一个子类的social_auth.middleware.SocialAuthExceptionMiddleware和覆盖默认行为(process_exception())重定向或设置在你所喜欢的方式喜欢的警告。

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

+0

我试着做选项#2但它没有成功。它成功地将用户登录出去,但不会作为新的social.user登录。 取代: MSG = '此{0}帐户已在使用中' 格式(提供商) 提高AuthAlreadyAssociated(strategy.backend,MSG) 用: 注销(kwargs.get( '请求')) user = social.user – nwilson5

+0

@omab:在使用Django的python社交授权中,我将如何无缝地在同一个请求中注销当前用户,并使用social_user管道替换为第二个用户设置会话? – jacob

+0

@omab:在social.actions.do_complete中,is_authenticated是在现有用户(“用户A”)的基础上设置的。但是,如果我在管道中注销“用户A”并返回“用户B”,do_complete将不会登录“用户B”,因为它已经被设置为True。 do_complete在管道完成后再次重新评估会话用户以确定是否登录“用户B”? – jacob

3

我的办法解决这个问题有点不同,而不是在管道解决这个,我确信,用户从未传递到摆在首位的管道。这样,即使social_auth.user与登录用户不匹配,social_auth.user也会登录到当前登录的用户的顶部。

我认为这与覆盖complete行动一样简单。人们想知道如何在蟒蛇 - 社会 - 身份验证版本的0.2.x覆盖social_user管道

urls.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) 
+1

随着时间的推移,我以前的解决方案似乎无法正常工作,或许使用最新的python社交认证。无论如何,你的解决方案确实能正常工作,而且肯定比我的解决方案简单。我从这个问题删除了我的。谢谢。 – jacob

+0

这是不工作的(原样),因为原来的'complete'视图略有改变。我必须在源代码中进行调整并稍微调整以匹配更改,但策略是稳定的,无条件地覆盖无条件传递无的用户参数。 –

+0

对我来说最新版本的完整功能(0.3.x版)https://maketips.net/tip/450/fix-authalreadyassociated-at-complete-this-account-is-already-in-use – user3479125

2

解决方案

在你的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', 
) 

在你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} 

,如果你愿意,你可以删除注释行。

+2

你的方法是注销当前用户。但它不会登录新认证的用户。任何帮助? – rishabsaraf93

0

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

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