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

时间:2022-09-11 14:45:31

In django-social-auth, there are a few instances where a backend will raise a ValueError (such as when a user cancels a login request or if a user tries to associate with an account that's already been associated with another User). If a User runs into one of these scenarios, they'll be presented with a 500 error on your site.

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

So, what's the best way to catch these? I'd prefer to be able to display a useful message (via the messages framework) when this happens, but I'm at a loss as to the best way to do this.

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

I'm thinking about writing my own view (in a separate app) that just wraps social_auth's associate_complete view, but this seems clunky... any ideas?

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

I could fork django-social-auth and customize this behavior, but I'd prefer not to maintain a separate fork--especially since I can't assume everone would want to handle these Exceptions in the same manner.

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

4 个解决方案

#1


13  

I've ecountered the same problem and it seems, that creating wrapper view is the best way to handle this situation, at this point, atleast. Here is how I had mine done:

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

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

You will have to setup url for it:

你必须为它设置url:

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

And then use it as before in template:

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

<a href="{% url 'users-social-auth-login' "google" %}">Log in with Google</a>

Hope this helps, even aftern two months after question was asked :)

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

#2


19  

Rather old question but worth mention that recent version of DSA supports a custom exception processor where you can do whatever you want with the exception message. The default version stores them in the messages app.

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

Also the exceptions are differentiated now instead of the not-useful ValueError used. Check the docs http://django-social-auth.readthedocs.org/en/latest/configuration.html.

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

Update (13/08/2013):

更新(2013年8月13日):

Since I've posted the above things have changed, now DSA has an exception middleware that when enabled stores the exception message in the jango builtin messages app. It's preferable to subclass the middleware and add the custom behavior to it. Check the doc at http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware

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

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

#3


6  

You need add social auth middleware:

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

MIDDLEWARE_CLASSES += ('social_auth.middleware.SocialAuthExceptionMiddleware',)

If any error occurs user will be redirected to erorr url(LOGIN_ERROR_URL from settings).

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

For detailed explanation please see documentation: http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware

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

#4


4  

In my app's views.py:

在我的应用程序的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'))

Then in the Root URLconf (notice the order of these url patterns):

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

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

My associate_complete_wrapper url essentially hijacks social_auth's socialauth_associate_complete url.

我的associate_complete_wrapper url基本上劫持了social_auth的socialauth_associate_complete url。

#1


13  

I've ecountered the same problem and it seems, that creating wrapper view is the best way to handle this situation, at this point, atleast. Here is how I had mine done:

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

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

You will have to setup url for it:

你必须为它设置url:

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

And then use it as before in template:

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

<a href="{% url 'users-social-auth-login' "google" %}">Log in with Google</a>

Hope this helps, even aftern two months after question was asked :)

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

#2


19  

Rather old question but worth mention that recent version of DSA supports a custom exception processor where you can do whatever you want with the exception message. The default version stores them in the messages app.

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

Also the exceptions are differentiated now instead of the not-useful ValueError used. Check the docs http://django-social-auth.readthedocs.org/en/latest/configuration.html.

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

Update (13/08/2013):

更新(2013年8月13日):

Since I've posted the above things have changed, now DSA has an exception middleware that when enabled stores the exception message in the jango builtin messages app. It's preferable to subclass the middleware and add the custom behavior to it. Check the doc at http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware

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

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

#3


6  

You need add social auth middleware:

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

MIDDLEWARE_CLASSES += ('social_auth.middleware.SocialAuthExceptionMiddleware',)

If any error occurs user will be redirected to erorr url(LOGIN_ERROR_URL from settings).

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

For detailed explanation please see documentation: http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware

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

#4


4  

In my app's views.py:

在我的应用程序的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'))

Then in the Root URLconf (notice the order of these url patterns):

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

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

My associate_complete_wrapper url essentially hijacks social_auth's socialauth_associate_complete url.

我的associate_complete_wrapper url基本上劫持了social_auth的socialauth_associate_complete url。