Reputation: 4745
I have a Rails-API app. More or less "out of the box" but I want to add back cookie-based session store. Here is what I've done:
app/controllers/application_controller.rb
+ include ::ActionController::Cookies
config/application.rb
+ config.middleware.insert_after ActiveRecord::QueryCache, ActionDispatch::Cookies
+ config.middleware.insert_after ActionDispatch::Cookies, ActionDispatch::Session::CookieStore
created config/initializers/secret_token.rb
+ Namespace::Application.config.secret_token = 'token'
created config/initializers/session_store.rb
+ Namespace::Application.config.session_store :cookie_store, :key => '_namespace_key'
When I inspect the session in a controller it results:
<Rack::Session::Abstract::SessionHash:0x3fdadc5daa24 not yet loaded>
However it does appear that data is being written to and used.
But, in my browser the cookie itself is being named as '_session_id' instead of '_namespace_key'
I thought I added back every piece required for cookie based session storage, but I appear to be missing something else. Any ideas?
Upvotes: 46
Views: 25718
Reputation: 90
This thread worked the magic for me. I was on Rails "7.0.4"
and Ruby "3.1.2"
config.session_store :cookie_store, key: '_interslice_session'
config.middleware.use ActionDispatch::Cookies
config.middleware.use config.session_store, config.session_options
Below is the User.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :jwt_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable, :lockable,
:timeoutable, :trackable, jwt_revocation_strategy: JwtDenylist
end
Upvotes: 4
Reputation: 34113
This worked for me in Rails 6.0, application.rb
:
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore
config.middleware.insert_after(ActionDispatch::Cookies, ActionDispatch::Session::CookieStore)
If you want to set custom key (yes, it has to be set twice):
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore, key: '_your_app'
config.middleware.insert_after(ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, key: '_your_app')
And lastly, if you want to add expiration date - it's done here:
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore, key: '_your_app', expire_after: 20.years
config.middleware.insert_after(ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, key: '_your_app')
Would have loved linking to documentation, but there's none.
Upvotes: 10
Reputation: 1045
If you're on Rails 5, and want to preserve config.api_only = true
you could extend the middleware to add the sessions layer, adding this code after class Application < Rails::Application
in config/application.rb
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore, key: '_namespace_key'
This could come in handy when you want to have a rails api-only
enabled app but have to manage user sessions with an administration panel like ActiveAdmin or Rails_Admin.
Upvotes: 56
Reputation: 3000
This line is ignored because you are not using the full Rails stack:
::Rails.application.config.session_store :cookie_store,
:key => '_namespace_key'
So instead, your session is using the default session key set here. However, you can pass these arguments directly by replacing:
config.middleware.insert_after
ActionDispatch::Cookies, ActionDispatch::Session::CookieStore
with:
config.middleware.insert_after
ActionDispatch::Cookies, ActionDispatch::Session::CookieStore,
:key => '_namespace_key'
Here's a full list of options you can pass (with a rough idea of their defaults, since some may be overridden by modules in Rails).
Upvotes: 9
Reputation: 40333
You need to remove these middleware declarations from your application.rb
file and add this:
config.api_only = false
This will enable session management the way you want if there is a configured session_store
somewhere in your initialisers (which you have). This isn't clearly documented, but that's what you're supposed to do.
Example here.
Upvotes: 13