Compojure/Ring: Почему сеанс с файлом cookie не перезагружается?

У меня есть приложение compojure, которое использует оболочку сеанса вызова для хранения токена OAuth, связанного с текущим пользователем. Я хочу, чтобы этот токен оставался доступным, когда сервер перезагружается, так что мне не нужно каждый раз проходить через auth-процесс.

Я предположил, что использование хранилища cookie вместо хранилища памяти по умолчанию поможет, но это не так. Что мне не хватает?

Это важная часть кода:

(defn auth-callback-handler
  [session {code :code}]
  (let [token (retrieve-token code)]
    (-> (redirect "/") (assoc :session (assoc session :token token)))))

(defroutes app-routes
  (GET "/" {session :session} (root-handler session))
  (GET "/auth-callback" {session :session params :params} (auth-callback-handler session params))
  (route/not-found "Not Found"))

(def app
  (-> (handler/site app-routes)
      (wrap-session {:store (cookie-store {:key "a 16-byte secret"})})))

Функция root-handler использует токен, чтобы решить, зарегистрирован ли кто-либо или нет, но не возвращает ничего в виде информации о сеансе.

Ответ 1

Проблема заключается в том, что у вас в приложении есть 2 wrap-session middlewares, так как у обработчика/сайта есть один. Это приводит к тому, что шифрование/дешифрование выполняется дважды. Чтобы настроить дескриптор сеанса compojure, используйте:

(def app
  (site app-routes {:session {:store (cookie-store {:key "a 16-byte secret"})}}))

Кроме того, возможно, вас будут интересовать некоторые из этих проектов, которые реализуют кольцевой протокол SessionStore:

https://github.com/sritchie/couch-session

https://github.com/wuzhe/clj-redis-session

https://github.com/rmarianski/servlet-session-store

Чтобы сделать последнее постоянным, вам нужно будет проверить документацию вашего контейнера сервлета по выбору.