I've got a Rails app for which I'm storing sessions in the database using activerecord-session_store. I want to prevent the creation of sessions for users that aren't logged in, because right now every crawler that hits the front page of the site gets a session that persists in the DB.
My app uses Rails 4.2.0, activerecord-session_store 0.1.1, and Devise 3.5.2.
Session creation is handled by Rack and the commit_session
method in Rack::Session::Abstract::ID provides an option to drop the session. I wrote a filter method in my ApplicationController
to drop the session if Devise's current_user
isn't defined:
after_filter :skip_session
def skip_session
unless current_user
request.session_options = {drop: true}
end
end
This prevents session creation1, but still allows sessions for logged in users. This even allows users to login (pretty important)—they visit the login page without a session but upon submitting the form Devise sets current_user
before this filter runs, thereby creating the session.
1: actually, the session is created and just not committed; in my case committing is to the DB, but if you use Rails' default cookie sessions, this would prevent sending the session cookie.
In Rails 5.2.0 use:
request.session_options[:skip] = true
May result in ActionController::InvalidAuthenticityToken
error when submitting sign in or sign up forms. Validating authenticity tokens in protect_from_forgery
seems to rely on the session. Quickfix: Disable in controller (eg. SessionsController):
skip_before_action :verify_authenticity_token, only: [:create]
In order for sign out to work:
skip_after_action :skip_session, only: [:destroy]