Add Rack Middleware for transitioning existing sessions

This checks if the current request has been submitted using the old session key (_session_id) and transparently migrates the session id to a new session cookie with the new settings and the new key (_ofn_session_id).
This commit is contained in:
Matt-Yorkley
2021-08-22 15:42:37 +01:00
parent e6ac57ac3a
commit 1d472d0dec
2 changed files with 45 additions and 1 deletions

View File

@@ -21,9 +21,9 @@ require "rails"
end
require_relative "../lib/open_food_network/i18n_config"
require_relative '../lib/spree/core/environment'
require_relative '../lib/spree/core/mail_interceptor'
require_relative "../lib/session_cookie_upgrader"
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
@@ -34,6 +34,15 @@ end
module Openfoodnetwork
class Application < Rails::Application
config.middleware.insert_before(
ActionDispatch::Cookies,
SessionCookieUpgrader, {
old_key: "_session_id",
new_key: "_ofn_session_id",
domain: "." + ENV["SITE_URL"].delete_prefix("www.")
}
) if Rails.env.staging? || Rails.env.production?
config.after_initialize do
# We need this here because the test env file loads before the Spree engine is loaded
Spree::Core::Engine.routes.default_url_options[:host] = 'test.host' if Rails.env == 'test'

View File

@@ -0,0 +1,35 @@
# frozen_string_literal: true
class SessionCookieUpgrader
def initialize(app, options = {})
@app = app
@options = options
end
def call(env)
request = ::Rack::Request.new(env)
cookies = request.cookies
old_key = @options[:old_key]
new_key = @options[:new_key]
# Set the session id for this request from the old session cookie (if present)
# This must be done before @app.call(env) or a new session will be initialized
cookies[new_key] = cookies[old_key] if cookies[old_key]
status, headers, body = @app.call(env)
if cookies[old_key]
# Create new session cookie with pre-existing session id
Rack::Utils.set_cookie_header!(
headers,
new_key,
{ value: cookies[old_key], path: "/", domain: @options[:domain] }
)
# Delete old session cookie
Rack::Utils.delete_cookie_header!(headers, old_key)
end
[status, headers, body]
end
end