在django-social-auth
中,有一些后端将引发ValueError
的情况(例如,当用户取消登录请求或用户尝试与已关联的帐户关联时)与另一个用户)。如果用户遇到其中一种情况,他们将在您的网站上显示500错误。
那么,抓住这些最好的方法是什么?当发生这种情况时,我宁愿能够显示一条有用的消息(通过消息框架),但我不知道最好的方法。
我正在考虑编写自己的视图(在一个单独的应用程序中),只包含social_auth
的{{1}}视图,但这看起来很笨拙......任何想法?
我可以fork associate_complete
并自定义此行为,但我不想维护一个单独的fork - 特别是因为我不能认为任何人都想以同样的方式处理这些异常。
答案 0 :(得分: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)
答案 1 :(得分: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))
您必须为其设置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>
希望这有帮助,即使在提出问题两个月后也是如此:)
答案 2 :(得分:6)
您需要添加社交身份验证中间件:
MIDDLEWARE_CLASSES += ('social_auth.middleware.SocialAuthExceptionMiddleware',)
如果发生任何错误,用户将被重定向到erorr url(设置中的LOGIN_ERROR_URL)。
详细说明请参阅文档: http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware
答案 3 :(得分: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'))
然后在Root URLconf中(注意这些url模式的顺序):
url(r'^associate/complete/(?P<backend>[^/]+)/$', 'myapp.views.associate_complete_wrapper'),
url(r'', include('social_auth.urls')),
我的associate_complete_wrapper
网址基本上劫持了social_auth的socialauth_associate_complete
网址。