Странная ошибка управления сессиями при смешивании 'wrap-defaults' кольца и `wrap-noir-сессии lib-noir`
У меня есть ring
веб-приложение, которое использует noir.session
следующее:
(def app (-> app-routes
(session/wrap-noir-session)
(wrap-defaults site-defaults))) ; both from ring.middleware.defaults
Однако кажется, что переменные сеанса теряются между запросами. Сервер продолжает отправлять Set-Cookie
заголовок, хотя клиент предоставляет Cookie
заголовок.
Используя метод проб и ошибок, я обнаружил, что, когда я отключаю анти-подделку кольца следующим образом, один и тот же сеанс живет между запросами:
(def app (-> app-routes
(session/wrap-noir-session)
(wrap-defaults (assoc-in site-defaults [:security :anti-forgery] false))))
но, конечно, я не хочу этого. Почему, и как я могу исправить свою проблему, не рискуя CSRF-атаками?
1 ответ
Просматривая исходный код всех задействованных промежуточных программ, я обнаружил, что lib-noir's wrap-noir-session
повторно реализует части кольца wrap-session
, Это привело меня к следующему эксперименту:
(def app (-> app-routes
(session/wrap-noir-session {:store (memory-store)})
(wrap-defaults (assoc site-defaults :session false))))
Здесь также сеансы живут через запросы.
Вот виновник: wrap-defaults
уже применяется wrap-session
так что когда wrap-noir-session
обработчик также указан, wrap-session
на самом деле вызывается дважды.
Окончательное решение не может быть проще: используйте wrap-noir-session*
вместо. Согласно документам, он "ожидает, что wrap-сессия уже была использована". Кажется, наоборот wrap-noir-session
,
(def app (-> app-routes
(session/wrap-noir-session*)
(wrap-defaults site-defaults)))
Надеюсь, это сэкономит вам время.