【问题标题】:How can I handle Exceptions raised by django-social-auth?如何处理 django-social-auth 引发的异常?
【发布时间】:2011-06-24 04:20:37
【问题描述】:

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

那么,捕捉这些的最佳方法是什么?发生这种情况时,我希望能够(通过消息框架)显示有用的消息,但我不知道最好的方法。

我正在考虑编写我自己的视图(在一个单独的应用程序中),它只是包装 social_authassociate_complete 视图,但这似乎很笨拙......有什么想法吗?

我可以 fork django-social-auth 并自定义此行为,但我不想维护单独的 fork ——尤其是因为我不能假设每个人都希望以相同的方式处理这些异常。

【问题讨论】:

    标签: django authentication social django-socialauth


    【解决方案1】:

    相当老的问题但值得一提的是,最新版本的 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)     
    

    【讨论】:

    • 这是一个正确的方向,但仍然是自定义处理功能cannot return an URL used in the subsequent redirection..
    • 你好@omab,我也对在 DSA v0.7.25 中处理异常的“官方方式”感兴趣。我不明白如何使用自定义异常处理器,你能给我们举个例子吗?提前致谢。
    • 我的答案的更新,因为我已经发布了它,所以事情发生了变化,现在 DSA 有一个异常中间件,当启用时,它将异常消息存储在 jango 内置消息应用程序中。最好对中间件进行子类化并向其中添加自定义行为。在django-social-auth.readthedocs.org/en/latest/…查看文档
    • 我最近在一个新项目中安装了 DSA,我真的很喜欢现在的情况。做得好!至于这个问题,我想更新它,让人们知道新的变化,但我很犹豫要改变原来的问题。我应该链接到您的答案/更新评论吗?想法?
    • @omab,我已经发布了一个示例自定义中间件,非常感谢您分享您的工作!如果不是很好的样本,请删除。
    【解决方案2】:

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

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

    你必须为它设置url

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

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

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

    希望这会有所帮助,即使是在提出问题两个月后 :)

    【讨论】:

    • 感谢您的回答!这基本上就是我所做的。为了比较,我将添加一个包含我编写的用于包装 associate_complete 的代码的答案。
    【解决方案3】:

    您需要添加社交认证中间件:

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

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

    详细解释请看文档: http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware

    【讨论】:

    • 仅供参考:此解决方案适用于我,但需要将 DEBUG 设置为 False,如果为 True,您将看到异常并且不会发生重定向。显然 django_social_auth (0.7.22) 在阅读该标志时做得不好。在这里发表评论,因为它让我花了 1 个小时在我的开发环境中弄清楚这一点。
    【解决方案4】:

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

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

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

    我的associate_complete_wrapper url 实质上劫持了 social_auth 的socialauth_associate_complete url。

    【讨论】:

      猜你喜欢
      • 2017-11-11
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      • 2018-04-18
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多