Доброе время!
Имею urls.py:
auth = JSONAuthentication()
user_handler = Resource(UserHandler, auth)
urlpatterns = patterns('',
url(r'^login/$', user_handler, { 'emitter_format': 'json' }),
)
Авторизация работает как. Сначала challenge 401, отправляю username и password, request.user устанавливается какой нужно. дальше в handlers.py:
class UserHandler(BaseHandler):
allowed_methods = ('POST',)
def create(self, request):
auth.login(request, request.user)
return {u'user':unicode(request.user)}
т.е. делаю login, django в auth.login пишет request.session['_auth_user_id']=user.id, далее оно сохраняется в базу сессий.
С этим всем хозяйством разобрался, отдебажил. Дальше в браузере жму F5, ожидаю, что сессия (длиной в неделю) сохранится и request.user заполнится по имеющейся сессии...
Срабатывает опять авторизация, в авторизации предварительно ищу юзера в сессии:
class JSONAuthentication(object):
....
def is_authenticated(self, request):
user = auth.get_user(request)
....
И вот тут оказывается, что auth.get_user ищет в сессии request.session['_auth_user_id'], которой там нет, и отваливается. В сессии на этот момент есть только sessionid=<правильная сессия>, по которой надо получить сессию из базы - по коду оно дальше - и там уже user_id будет и проч...
Вот я думаю, либо неправильно что-то делаю, либо что-то не допилил.
ЗЫ используется связка python 2.7, django 1.3, piston (rest), pymongo (база), mango (хранение сессий и юзеров в mongodb)
UPD Проблему решить удалось, осталось выяснить чей косяк. Мой или pymongo :)
Ответ
Проблему удалось решить двумя способами. Сложный. Проблема была в том, что сессия не восстанавливалась (обращение в auth.get_user к request.session['_auth_user_id'] вызывало восстановление сессии). При восстановлении возникало исключение UnicodeEncodeError в pymongo'вском bson.Objectid, который pymongo не обрабатывают (обработывается только UnicodeDecodeError, т.е. зеркальный эксепшин). Добавление в __setstate__ дополнительного UncodeEncodeError в секцию except решало проблему. Написал краткий тест с минимальными вызовами для выявления бага, в шелле он отрабатывал как надо, а в eclipse при отладке в частности валился, притом молчаливо - except перекрывал исключение, но не обратывал его. Пытался даже с pymongo'вцами разобраться, у них тоже в шелле все прекрасно работало. Оттуда выяснился более простой метод "исправления". Простой метод основан на том, что pydev в eclipse при старте приложения устанавливает свои параметры консоли, в частности меняет дефолтную кодировку (которая указывается в настройках pydev'а). Из-за нее-то и возникала проблема. У меня стояла в настройках cp1251, а в шелле - ascii, при которой работало все. Установил в настройках pydev'а ascii (utf-8 тоже можно как оказалось) и все заработало. В инете много где пишут про этот баг, мол setdefaultencoding - evil, evil, evil и в частности про pydev этим занимающийся в частности. Относительно pymongo, не знаю баг ли это в pymongo - то, что при одной дефолтной кодировке работает, при другой не хочет, решать им конечно, но имхо, стоит добавить этот злосчастный UnicodeEncodeError, хотя я видимо был бы единственным, кого это коснулось. UPD Разработчики pymongo признали такое поведение как ошибку, связанную с кодировками, используемыми в настройках сайта. В транк внесены изменения, убрана заглушка от ошибки преобразования из неизвестной кодировки в latin-1. Внесена корректная проверка значения, восстанавливаемого через pickle. В общем рад, что смог помочь выяснить причины, что привело к более правильному коду.
Комментариев нет:
Отправить комментарий