我很欣赏一个基本的基座示例,说明如何(1)设置服务器重启后的cookie,以及(2)使用基于cookie的会话;特别是如何获取和设定值。
我很惊讶没有找到使用ring.middleware.session/wrap-session
的示例(源代码:https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/session.clj)。
根据此Pedestal sample code for using Ring middleware,您需要为service.clj
添加两项关键内容。首先,定义会话拦截器:
; aliases for namespace :require
[io.pedestal.http.ring-middlewares :as middlewares]
[ring.middleware.session.cookie :as cookie]
(definterceptor session-interceptor
(middlewares/session {:store (cookie/cookie-store)}))
示例代码有这个警告,但是:
在这个示例代码中,我们没有指定用于的秘密 会话数据在被发送回之前被加密 浏览器。这有两个后果,第一个是我们需要的 在整个服务中使用相同的拦截器实例,以便 会话数据对所有路径都是可读写的。第二 结果是当会话数据变得无法恢复时 服务器进程结束。即使浏览器保留了 cookie,它不是不可恢复的密文和会话 拦截器将其视为不存在。
如何克服上述限制?
然后,将session-interceptor
添加到您的路线中(以下是我的示例代码):
(defroutes routes
[[["/"
{:get [:root root/index]}
^:interceptors [session-interceptor
(body-params/body-params)
bootstrap/html-body]]]]
我知道上面的设置步骤会导致Ring中间件向请求映射添加:session
密钥。这样很容易:(:session request)
。但是我如何以及在何处添加会话?一个例子将不胜感激。
答案 0 :(得分:3)
现在,回答我的一些问题:
指定密钥意味着在服务器重新启动后,cookie支持的会话将可重新读取,如Compojure/Ring: Why doesn't a session with cookie-store survive a server restart?所述。以下是一些代码,说明如何:
; (:require [crypto.random :as random])
(def the-key (random/bytes 16)) ; run once
{:store (cookie-store {:key the-key})}
更改会话的价值时:
“要设置:session的值,只需将其与您的响应一起传递即可。如果您不需要更改会话,请在响应中保留:session。如果您想要实际清除会话,请将nil作为:session密钥的值传递。“(来自:Luke VanderHart and Ryan Neufeld. “Clojure Cookbook.”)