I'd appreciate a basic Pedestal example of how to (1) setup cookies that survive server restarts and (2) use cookie-based sessions; in particular how to get and set values.
I'm a little surprised not to find an example that uses ring.middleware.session/wrap-session
(source code here: https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/session.clj).
According to this Pedestal sample code for using Ring middleware, there are two key things to add to your service.clj
. First, define the session interceptor:
; 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)}))
The sample code has this caveat, however:
In this example code we do not specify the secret with which the session data is encrypted prior to being sent back to the browser. This has two consequences, the first being that we need to use the same interceptor instance throughout the service so that the session data is readable and writable to all paths. The second consequence is that session data will become unrecoverable when the server process is ended. Even though the browser retains the cookie, it is not unrecoverable cipher-text and the session interceptor will treat it as non-existent.
How do I overcome the above limitations?
And, second, add the session-interceptor
to your routes (the following is my example code):
(defroutes routes
[[["/"
{:get [:root root/index]}
^:interceptors [session-interceptor
(body-params/body-params)
bootstrap/html-body]]]]
I know that the setup steps above cause the Ring middleware to add a :session
key to the request map. So getting is easy: (:session request)
. But how and where do I add to the session? An example would be appreciated.
The cookie allows the server to identify the user and retrieve the user session from the session database, so that the user session is maintained. A cookie-based session ends when the user logs off or closes the browser. Cookie-based session management is secure and has performance benefits over alternatives.
The session cookie is a server-specific cookie that cannot be passed to any machine other than the one that generated the cookie. The session cookie allows the browser to re-identify itself to the single, unique server to which the client had previously authenticated.
About SessionID and CookiesAt the beginning of a new session, the server stores the Session ID in the user's Web browser as a cookie. The SessionID cookie is similar to a locker key in that, as the user interacts with an application during a session, ASP can store information for the user in a "locker" on the server.
This cookie stores information such as the user's input and tracks the movements of the user within the website. There is no other information stored in the session cookie. Session cookies are set on a device's temporary memory when a browser session starts.
For now, to answer some of my questions:
Specifying a key means that the cookie-backed sessions will be re-readable after a server restart, as mentioned by Compojure/Ring: Why doesn't a session with cookie-store survive a server restart?. Here is some code that shows how:
; (:require [crypto.random :as random])
(def the-key (random/bytes 16)) ; run once
{:store (cookie-store {:key the-key})}
When it comes to changing the value of a session:
“To set the value of :session, just pass it along with your response. If you don’t need the session changed, leave :session out of your response. If you want to actually clear the session, pass nil as the value of the :session key.” (from: Luke VanderHart and Ryan Neufeld. “Clojure Cookbook.”)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With