-
-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Session: writable from within Sente's router loop? #62
Comments
Hey Daniel! Sorry for the delay replying to your email btw, haven't forgotten - just a little swamped atm. This is a good question; I should actually address it in the README's FAQ. As with Ring generally, the session you see here is an immutable value so can't be modified directly. You've got a few options:
Does that make sense? |
Thank you for the elaborate response. There is a lot of food for thought here. I'm going to experiment and report back if I gain any insight. Thanks again! |
Cool. Anyway leaving this open until I've found some time to add an entry to the README's FAQ. Cheers :-) |
Closing with 5680a14. Feel free to reopen if you've got any follow-up questions, cheers :-) |
👍 |
I'm going to document my experiments on this very subject just for posterity's sake and as a reference for others (and me). The reason why one might need to write to the session in the first place is that sometimes you get user data outside of a ring request response cycle. Social signins and oauth dances are typical situations you might encounter. 1, If possible, prefer to write to the session in a ring request response cycle. As @ptaoussanis wrote: The example project uses this strategy for the login procedure- it fires off a standard Ajax request for the login form so that the auth (POST) handler can return a new session and have the Ring middleware handle the actual session update. 2, As @ptaoussanis wrote, you can actually write changes to the underlying mutable session store. Make sure you have a handle on the session store. (def session-store (atom {}))
(def site
(-> site-defaults
(assoc :session {:store (ring.middleware.session.memory/memory-store session-store)}))) From the client, send an event that you wish to autologin. Then, in the event handler on the server, you can manipulate the store like so: (match [event]
[[:mailer/api {:action :autologin}]] (when-let [data (:access-token-response (:oauth session))]
(let [user (api/new-user data)
key (:value (get cookies "ring-session"))]
(swap! session-store (fn [session] (assoc-in session [key :uid] (:login_name user))))))
:else (println "Unmatched event:" event)) Finally, you might need to call 3, Define Ring middleware to detect oauth credentials in the session, and do the work there. (defn autologin [app]
(fn [{session :session :as request} ]
(if-let [data (:access-token-response (:oauth session))]
(let [user (api/new-user data)
session (assoc session :uid (:login_name user))]
(app (assoc request :session session)))
(app request)))) Add the middleware to your ring handler: (def app
(-> routes
(autologin)
(wrap-defaults site))) In summary, I think solution 1 and 3 are idiomatic and embrace the ring spirit, solution 2 is a bit hack-y. I hope this will help future generations. |
Hey Daniel, updated the README with a link to your comment here (thanks!): https://github.com/ptaoussanis/sente#how-can-server-side-channel-socket-events-modify-a-users-session |
👍 |
So I know that I can read session properties inside Sente's router loop, but can I write to it as well?
For example, how would I go about writing
fn-that-writes-and-persists-a-session-property
?The text was updated successfully, but these errors were encountered: