在Ring中,会话(Sessions)的工作方式可能跟你预计的有一点不同,因为Ring试图尽可能的变得函数式化.
会话数据通过请求map中的:session
key被传递.下面的例子打印出会话中的当前的用户名.
- (use 'ring.middleware.session
- 'ring.util.response)
- (defn handler [{session :session}]
- (response (str "Hello " (:username session))))
- (def app
- (wrap-session handler))
为了改变会话数据,你可以添加一个包含更新过后的会话数据的:session
key到一个响应中.下一个例子统计了当前会话访问页面的次数.
- (defn handler [{session :session}]
- (let [count (:count session 0)
- session (assoc session :count (inc count))]
- (-> (response (str "You accessed this page " count " times."))
- (assoc :session session))))
为了完全删除session,在响应中设置:session
key为nil
:
- (defn handler [request]
- (-> (response "Session deleted.")
- (assoc :session nil)))
如果你想简单的重新创建会话,由于特权提升,添加:recreate
key到会话元数据(metadata)中.这将会导致会话标识符被发送到浏览器,由此去改变.
- (defn handler [request]
- (-> (response "Session identifier recreated")
- (assoc :session (vary-meta (:session request) assoc :recreate true))))
经常性的你想要控制会话cookie在用户的浏览器上存在多长时间.你可以使用:cookie-attrs
选项去改变会话cookie的属性:
- (def app
- (wrap-session handler {:cookie-attrs {:max-age 3600}}))
在这个例子中,cookie的最大生命周期被设置成3600秒,或者1小时.
你也可以使用这个选项确保站点的会话cookie通过HTTPS被保护而不是通过HTTP被泄露:
- (def app
- (wrap-session handler {:cookie-attrs {:secure true}}))
会话存储
会话数据被存储在会话储存中,Ring里面有两个储存方式:
ring.middleware.session.memory/memory-store
- 在内存中储存会话ring.middleware.session.cookie/cookie-store
- 储存加密的会话到一个cookie上
默认情况下,Ring存储会话数据在内存中,但是这可以被:store
选项重写:
- (use 'ring.middleware.session.cookie)
- (def app
- (wrap-session handler {:store (cookie-store {:key "a 16-byte secret"})})
通过实现ring.middleware.session.store/SessionStore
protocol,你可以编写自己的会话储存方式:
- (use 'ring.middleware.session.store)
- (deftype CustomStore []
- SessionStore
- (read-session [_ key]
- (read-data key))
- (write-session [_ key data]
- (let [key (or key (generate-new-random-key))]
- (save-data key data)
- key))
- (delete-session [_ key]
- (delete-data key)
- nil))
注意当你编写会话,如果这是一个新的会话,key将会是nil的.会话储存方式应该预计是这样的,而且会生成一个随机key.这是十分重要的,这个key不会被猜解出,否则恶意的用户能够访问其他用户的会话数据.
当前内容版权归 clojure-china 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 clojure-china .