Странная ошибка управления сессиями при смешивании '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)))

Надеюсь, это сэкономит вам время.

Другие вопросы по тегам