Rack: Rack::Session::Cookie: why not delete the cookie?

Created on 27 Oct 2017  路  3Comments  路  Source: rack/rack

Calling #destroy on a Rack::Session::Abstract::Persisted subclass clears the session hash and calls #delete_session.

The implementation of #delete_session in Rack::Session::Cookie states: https://github.com/rack/rack/blob/51356a65185d6c74f7e588ec468ad64ca3a49bcb/lib/rack/session/cookie.rb#L173

But there is something it can do: send a Set-Cookie header that deletes (expires) the cookie on the client. Instead, it simply creates a blank session and sends that along to the client. Why not delete the cookie?

Most helpful comment

The primary blocker seems to be that the Rack::Session::Abstract::Persisted#delete_session stub has no way access to the response object, so we'd have to change the calling signature of that method, which could potentially have some wide-ranging impact.

Here's the workaround I'm using in the meantime. Hopefully this will help a future googler:

post '/logout' do
  options = env[Rack::RACK_SESSION_OPTIONS]
  options[:drop] = true # prevent delete_session from generating a new sid
  session.destroy
  # Rack sends a cookie with an empty session, but let's tell the browser to actually delete the cookie.
  response.delete_cookie('rack.session', :domain=>options[:domain], :path=>options[:path])
  nil
end

All 3 comments

Good question. Please do investigate, and if we can set the cookie header to expires the cookie open a PR. Thanks

The primary blocker seems to be that the Rack::Session::Abstract::Persisted#delete_session stub has no way access to the response object, so we'd have to change the calling signature of that method, which could potentially have some wide-ranging impact.

Here's the workaround I'm using in the meantime. Hopefully this will help a future googler:

post '/logout' do
  options = env[Rack::RACK_SESSION_OPTIONS]
  options[:drop] = true # prevent delete_session from generating a new sid
  session.destroy
  # Rack sends a cookie with an empty session, but let's tell the browser to actually delete the cookie.
  response.delete_cookie('rack.session', :domain=>options[:domain], :path=>options[:path])
  nil
end

Without giving destroy access to the response, I think the current behavior is best. The problem with giving destroy access to the response is it couples the Rack::Session::Abstract::Persisted to Rack::Response (or something implementing a similar API). I think this issue cannot be handled well by rack itself, and should be handled by a higher level web framework that can destroy the session as well as delete the cookie. Since I don't think the current behavior is a bug, I'm going to close this now.

Was this page helpful?
0 / 5 - 0 ratings