每次保存都会重置响铃会话(Compojure)

Ring session being reset with each save (Compojure)

每次我在 Ring 项目中保存 Clojure 源文件时,会话都会重置。

注意 ring-session ID。我先保存我的 handler.clj 文件:

2015-03-17 11:02:51,857 INFO  onelog.core: Starting :get / for 127.0.0.1 {"accept-encoding" "gzip, deflate, sdch", "cache-control" "max-age=0", "connection" "keep-alive", "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36", "accept-language" "en-US,en;q=0.8", "accept" "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "host" "localhost:3000", "cookie" "ring-session=40575c9e-fbe9-4fd5-8624-d5e4ef9d98a9"}
2015-03-17 11:02:51,859 INFO  onelog.core: Finished :get / for 127.0.0.1 in (2 ms) Status: 404
2015-03-17 11:03:01,147 INFO  onelog.core: Starting :get / for 127.0.0.1 {"accept-encoding" "gzip, deflate, sdch", "cache-control" "max-age=0", "connection" "keep-alive", "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36", "accept-language" "en-US,en;q=0.8", "accept" "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "host" "localhost:3000", "cookie" "ring-session=26aadcce-e665-43df-afa5-0f09f98351ac"}
2015-03-17 11:03:01,149 INFO  onelog.core: Finished :get / for 127.0.0.1 in (2 ms) Status: 404

如果您使用已登录的用户,这可能会变得很麻烦,每次更改时都必须重新登录。

这是我的处理程序中的内容:

(def app
  (-> app-routes
      (friend/authenticate auth-config)
      (wrap-defaults site-defaults)  
      (logger/wrap-with-logger)))

我是不是遗漏了什么明显的东西?

您在创建 (def) 处理程序时可能正在实例化一个新的会话存储。有多种解决问题的方法。一种直接的方法是使用 defonce 定义单个会话存储并在创建新处理程序时重用它。如果您需要多个独立的处理程序(用于测试等),那将导致问题。查看组件以获得更全面的解决方案。

OP更新后:

(wrap-defaults req site-defaults) 此处会在每次评估时创建一个新的(内存中,空的)会话存储,因此只要调用 (def app ...),您所有的旧会话都将失效。

一个简单的解决方案是使用

(defonce app
  (-> #'app-routes ;; reevaluate app-routes at every request
      (friend/authenticate auth-config)
      (wrap-defaults site-defaults)  
      (logger/wrap-with-logger)))

这样就可以在不重置会话的情况下加载包含应用程序的文件,但代价是添加中间件会更加繁琐。

更多涉及的替代方案包括使用持久的(磁盘、数据库、memcached 等)或基于纯 cookie 的(客户端)会话存储,它们在重新加载 wrap-defaults 时不会被清空。请参阅 wrap-defaultsring.middleware.session

的文档