Страницы

Поиск по вопросам

суббота, 9 марта 2019 г.

Авторизация и сессии в django и piston

Доброе время! Имею 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. В общем рад, что смог помочь выяснить причины, что привело к более правильному коду.

Комментариев нет:

Отправить комментарий