会话 - snakevash/ring-clojure-doc-cn GitHub Wiki

Ring的会话工作方式会有点不同, Ring视图更具函数式。

会话数据是通过:session键来传输。 示例:

(use 'ring.middleware.session
     'ring.util.response)

(defn handler [{session :session}]
  (response (str "Hello " (:username session))))

(def app
  (wrap-session handler))

如何改变会话数据, 你可以增加:session来更新数据。示例:

(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值为nil:

(defn handler [request]
  (-> (response "Session deleted.")
      (assoc :session nil)))

当然你会控制会话在客户端的时间长度。你可以修改会话的cookie属性,:cookie-attrs:

(def app
  (wrap-session handler {:cookie-attrs {:max-age 3600}}))

以上有效期为一个小时。

使用HTTPS:

(def app
  (wrap-session handler {:cookie-attrs {:secure true}}))

Session Stores 会话保存

会话数据保存在会话中心. 有两种方式:

  • 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协议:

(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))

注意:在写会话的时候, 新会话为nil。 会话标识是随机,为了安全起见。