Как проверить поддержку файлов cookie браузера с помощью Pyramid - PullRequest
3 голосов
/ 15 февраля 2012

Я хотел бы знать, когда подходящий момент и как проверить поддержку файлов cookie браузера.

Я понимаю, что должен проверить следующий запрос и, например, с помощью мензурки, найти ключ сеанса _creation_time или request.headers['Cookie'] ... и вызвать исключение, если не найден, но я не хочу этого делать или что-то подобное для каждого запроса. Некоторые части моего приложения не требуют куки, такие как домашняя страница или информация, часто задаваемые вопросы ...

Когда пользователь выходит из системы, сеанс удаляется или становится недействительным, и я использовал для перенаправления на домашний вид, если я проверю session key в этот момент, я не найду его, но это не значит, что есть этот вопрос.

Пример, который я использовал в начале просмотра логина:

 try: request.headers['Cookie']
 except KeyError:
   return HTTPFound(location=request.route_url('home'))

Обратите также внимание, что если я попытаюсь напечатать сообщение об ошибке с помощью request.session.flash(msg, 'error') или снова использовать фрагмент в начале домашнего просмотра и обработать сообщение с шаблоном, используя переменную возврата элемента управления, после выхода из системы оно будет ошибочным отображается.

Я ищу самый элегантный способ решения проблемы ... может быть, подписаться на событие? ... записать функцию для вызова в некотором заинтересованном представлении?

1 Ответ

3 голосов
/ 15 февраля 2012

Есть несколько причин, которые могут стать причиной ваших проблем.

Прежде чем я продолжу ... FYI Pyramid использует WebOb для обработки объектов запроса и ответа

Сценарий 1

Если вы вызываете set_cookie из Pyramid,а затем сделать перенаправление, set_cookie не будет отправлено.Это потому, что перенаправления создают новый объект ответа.

Есть несколько способов обойти это:

  1. Самое простое - просто скопировать заголовки ответа в файл cookie при поднятии / возврате перенаправления

    return HTTPfound( "/path/to/redirect", headers=[ (k,v) for (k,v)\
    in self.request.response.headers.iteritems() if k == 'Set-Cookie']  )
    

    ИЛИ

    resp = HTTPFound(location='/path/to/redirect') 
    return self.request.response.merge_cookies(resp) 
    

    Следует также отметить, что браузеры MOST принимают файлы cookie при перенаправлениях, а Safari - нет.

  2. другой способ - использовать крючки пирамиды.конвертировать куки за кулисами.Я написал подписчиков, которые автоматизируют это.они на pypi и github.https://github.com/jvanasco/pyramid_subscribers_cookiexfer

Сценарий 2

Существует два способа обработки сессий в Pyramid.Pyramid имеет свою собственную библиотеку сессий, а затем есть Beaker , который обрабатывает сессий для Pylons и имеет поддержку Pyramid, которую используют многие люди.Я не могу говорить о pyramid.session, но в Beaker есть два режима для уничтожения сеанса:

delete()
Delete the cookie, and clear the session

invalidate()
Clear the contents and start a new session

Если вы вызываете invalidate(), cookie сеанса Beaker остается прежним, и все данные сеанса очищаются- чтобы вы могли начать хранить новые данные в пустом объекте сеанса.

Если вы вызываете delete(), cookie уничтожается, как и данные сеанса.Если вы добавите новую информацию в сеанс, IIRC, она войдет в новый sessionid / cookie.Однако, как я отмечал в первой части выше, set_cookie будет вызываться, но затем выбрасываться во время перенаправления.Так что если вы delete() сеанс, а затем не переносите заголовки set_cookie ... клиент никогда не получит идентификатор сеанса.

Некоторые примеры поведения файлов cookie в пирамиде

Поведение перенаправления

  • Пользователь посещает сайт и получает cookie: SessionId = 1
  • Пользователь нажимает кнопку входа
    • Приложение сохраняет статус входа в сеанс "1"
    • Приложение вызывает set_cookie с" LoggedIn = 1 "
    • Перенаправление вызовов приложения в / home
    • Перенаправление отправлено, без файлов cookie
  • Пользователь попадает в / home
    • Приложение видит cookie только для "SessionId = 1"

Поведение удаления с перенаправлением:

  • Пользователь нажимает кнопку выхода
    • Приложение вызывает 'delete ()' в сеансе, уничтожает хранилище данных и помещает set_cookie в request.response, чтобы истечь срок действия старого cookie.если создается новый идентификатор сеанса, он также отправляется.
    • Если приложение отправляет ответ, клиент получает файлы cookie
    • Если приложение перенаправляет, клиент не получает заголовки для истечения срока действия файла cookie или установки.до нового

Поведение аннулирования с перенаправлением:

  • Пользователь нажимает кнопку выхода
    • Приложение вызывает 'invalidate ()'в сеансе уничтожение хранилища данных
    • Приложение устанавливает специальный файл cookie "loggedout = 0"
    • Если приложение отправляет ответ, клиент получает файлы cookie
    • Если приложение перенаправляет:
      • Клиент не получает заголовок «loggedout = 0»
      • У клиента все еще есть старый файл cookie сеанса, но он был признан недействительным / удален в бэкэнде, поэтому они фактически заблокированы.

примечание: лично мне не нравится использовать интерфейс request.headers, который обрабатывает все заголовки, для получения файлов cookie.Мне повезло больше с request.cookies - который возвращает словарь файлов cookie.

...