如何处理django-social-auth引发的异常?

Bra*_*ery 19 authentication django social django-socialauth

django-social-auth某些情况下,后端将引发一个ValueError(例如,当用户取消登录请求或用户尝试与已与其他用户关联的帐户关联时).如果用户遇到其中一种情况,他们将在您的网站上显示500错误.

那么,抓住这些最好的方法是什么?当发生这种情况时,我更愿意能够显示有用的消息(通过消息框架),但是我不知道最好的方法.

我正在考虑编写我自己的视图(在一个单独的应用程序中),只是包装social_authassociate_complete视图,但这看起来很笨拙......任何想法?

我可以分叉django-social-auth并自定义这种行为,但我宁愿不维护一个单独的fork - 特别是因为我不能认为任何人都想以同样的方式处理这些异常.

oma*_*mab 19

相当古老的问题,但值得一提的是,最新版本的DSA支持自定义异常处理器,您可以使用异常消息执行任何操作.默认版本将它们存储在消息应用程序中.

此外,现在区分异常而不是ValueError使用无用的异常.查看文档http://django-social-auth.readthedocs.org/en/latest/configuration.html.

更新(2013年8月13日):

由于我发布了以上内容已经发生变化,现在DSA有一个异常中间件,启用后会在jango内置消息应用中存储异常消息.最好是继承中间件并向其添加自定义行为.查看http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware上的文档

示例中间件:

# -*- coding: utf-8 -*-
from social_auth.middleware import SocialAuthExceptionMiddleware
from social_auth.exceptions import AuthFailed
from django.contrib import messages

class CustomSocialAuthExceptionMiddleware( SocialAuthExceptionMiddleware):

    def get_message(self, request, exception):
        msg = None
        if (isinstance(exception, AuthFailed) and 
            exception.message == u"User not allowed"):
            msg =   u"Not in whitelist" 
        else:
            msg =   u"Some other problem"    
        messages.add_message(request, messages.ERROR, msg)     
Run Code Online (Sandbox Code Playgroud)


Sil*_*ght 13

我已经遇到了同样的问题,似乎创建包装器视图是处理这种情况的最佳方式,至少在这一点上.这是我完成的方式:

def social_auth_login(request, backend):
    """
        This view is a wrapper to social_auths auth
        It is required, because social_auth just throws ValueError and gets user to 500 error
        after every unexpected action. This view handles exceptions in human friendly way.
        See https://convore.com/django-social-auth/best-way-to-handle-exceptions/
    """
    from social_auth.views import auth

    try:
        # if everything is ok, then original view gets returned, no problem
        return auth(request, backend)
    except ValueError, error:
        # in case of errors, let's show a special page that will explain what happened
        return render_to_response('users/login_error.html',
                                  locals(),
                                  context_instance=RequestContext(request))
Run Code Online (Sandbox Code Playgroud)

你必须url为它设置:

urlpatterns = patterns('',
    # ...
    url(r'^social_auth_login/([a-z]+)$',  social_auth_login, name='users-social-auth-login'), 
)
Run Code Online (Sandbox Code Playgroud)

然后像以前一样在模板中使用它:

<a href="{% url 'users-social-auth-login' "google" %}">Log in with Google</a>
Run Code Online (Sandbox Code Playgroud)

希望这有帮助,甚至在提出问题后两个月后问:)


Yev*_*lev 6

您需要添加社交身份验证中间件:

MIDDLEWARE_CLASSES += ('social_auth.middleware.SocialAuthExceptionMiddleware',)
Run Code Online (Sandbox Code Playgroud)

如果发生任何错误,用户将被重定向到erorr url(来自设置的LOGIN_ERROR_URL).

有关详细说明,请参阅文档:http: //django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware


Bra*_*ery 5

在我的应用程序的views.py中:

from social_auth.views import associate_complete

def associate_complete_wrapper(request, backend):
    try:
        return associate_complete(request, backend)
    except ValueError, e:
        if e and len(e.args) > 0:
            messages.error(request, "Failed to Associate: %s" % e.args[0])
    return redirect(reverse('pieprofile-edit-account'))
Run Code Online (Sandbox Code Playgroud)

然后在Root URLconf中(注意这些url模式的顺序):

url(r'^associate/complete/(?P<backend>[^/]+)/$', 'myapp.views.associate_complete_wrapper'),
url(r'', include('social_auth.urls')),
Run Code Online (Sandbox Code Playgroud)

我的associate_complete_wrapper网址实际上劫持了social_auth的socialauth_associate_complete网址。