Страницы

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

среда, 22 января 2020 г.

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

#сессия #pymongo #django


Доброе время!
Имею 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 :)    


Ответы

Ответ 1



Проблему удалось решить двумя способами. Сложный. Проблема была в том, что сессия не восстанавливалась (обращение в 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. В общем рад, что смог помочь выяснить причины, что привело к более правильному коду.

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

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