Как я могу обрабатывать исключения, поднятые django-social-auth?
В django-social-auth
есть несколько экземпляров, где бэкэнд будет поднимать ValueError
(например, когда пользователь отменяет запрос на вход или если пользователь пытается связать с учетной записью, которая уже была связана с другим пользователем), Если пользователь запускается в один из этих сценариев, на вашем сайте будет обнаружена ошибка 500.
Итак, что лучший способ поймать их? Я предпочел бы иметь возможность отображать полезное сообщение (через структуру сообщений), когда это произойдет, но я не понимаю, как это сделать.
Я подумываю написать собственное представление (в отдельном приложении), которое просто обертывает вид social_auth
associate_complete
, но это кажется неуклюжим... любые идеи?
Я мог бы развить django-social-auth
и настроить это поведение, но я бы предпочел не поддерживать отдельную вилку, тем более, что я не могу предположить, что everone захочет обрабатывать эти Исключения таким же образом.
Ответы
Ответ 1
Я затронул ту же проблему, и кажется, что создание оберточного представления - лучший способ справиться с этой ситуацией, на данный момент, по крайней мере. Вот как я сделал это:
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 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
Скорее старый вопрос, но стоит упомянуть, что недавняя версия DSA поддерживает специальный обработчик исключений, где вы можете делать все, что хотите, с сообщением об исключении. Версия по умолчанию хранит их в приложении сообщений.
Кроме того, исключения теперь различаются вместо используемого ValueError
. Проверьте документы http://django-social-auth.readthedocs.org/en/latest/configuration.html.
Обновление (13/08/2013):
Поскольку я опубликовал вышеизложенное, все изменилось, теперь у 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)
Ответ 3
Вам нужно добавить социальное промежуточное ПО:
MIDDLEWARE_CLASSES += ('social_auth.middleware.SocialAuthExceptionMiddleware',)
Если возникнет какая-либо ошибка, пользователь будет перенаправлен на erorr url (LOGIN_ERROR_URL из настроек).
Подробные объяснения см. в документации:
http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware
Ответ 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'))
Затем в Корневой URL-код (обратите внимание на порядок этих шаблонов url):
url(r'^associate/complete/(?P<backend>[^/]+)/$', 'myapp.views.associate_complete_wrapper'),
url(r'', include('social_auth.urls')),
Мой associate_complete_wrapper
url по существу захватывает URL-адрес social_auth socialauth_associate_complete
.