stimulus_reflex icon indicating copy to clipboard operation
stimulus_reflex copied to clipboard

cookie-backed session storage

Open leastbad opened this issue 5 years ago • 0 comments

Type of PR (feature, enhancement, bug fix, etc.)

Enhancement

Description

This PR restores support for cookie-backed session storage in SR. You can set cookie values in a Reflex action method, and they will be persisted the long way.

I had two major approaches I could choose. I initially chose the first path. We can evaluate the best option.

  1. Store the session data as a JSON blob in Redis so that there is no payload sent to the client.
  2. Use MessageVerifier to encode the session data, sent it to the client, client sends it back to the server as a parameter to the fetch call. This seems much more complex to me, given that Redis is a requirement of SR and caching must be enabled.

This PR is 90%ish done; I need help from you folks to figure out where in the codebase to to capture the session data, both before and after all of the callbacks have finished and the main method has finished executing. My intention is to only store and update the session data that changes during the course of the Reflex. More importantly, we don't want to send the update unless session data is changed.

Note that I have gated the update-cookies functions (even the route the engine adds) to applications that report using the CookieStore.

In the interim, I have created a Reflex action that proves the functionality works. You're supposed to use your imagination and picture the lines in the Reflex action below starting with "redis_key" and "Rails.cache" as happening in the background of the ultimate solution. :wink:

Rails.application.routes.draw do
  mount StimulusReflex::Engine => "/stimulus_reflex"
end
<button data-reflex="click->Runner#update_session">Session</button>
<%= session[:test] %>
def update_session
  redis_key = "stimulus_reflex:session:" + session.id.to_s
  session[:test] = 666
  Rails.cache.write redis_key, session.to_h.reject {|key| ["session_id", "_csrf_token"].include? key }.to_json
  morph :nothing
end

I'm really proud of this solution. I've never really modified an Engine on my own, before.

Why should this be added

A lot of people perceive cookie storage as a reasonable default and seem outraged when they can't use it.

Checklist

  • [x] My code follows the style guidelines of this project
  • [x] Checks (StandardRB & Prettier-Standard) are passing
  • [x] This is not a documentation update

leastbad avatar Feb 08 '21 06:02 leastbad