I'm using sessions in my Catalyst app via Session
, Session::Store::DBIC
, and Session::State::Cookie
.
I have a few controllers and methods that send out data with a Cache-Control: public
header, so its essential that the Set-Cookie:
header not go out with those responses (otherwise, it'd be cached and sent to other clients, leading to possible security issues). I haven't found a good way to accomplish this.
How can I tell Session
or Session::State::Cookie
to not send a cookie in response to a given request?
Doing a little RTFS, Session.pm
overrides Catalyst's finalize_headers
method and sets the cookie there, through a rather deep call chain:
finalize_header
⇒ _save_session_expires
⇒ session_expires
⇒ _extended_session_expires
⇒ extend_session_id (…::Session::State::Cookie)
⇒ update_session_cookie (…::Session::State::Cookie)
There does not appear to be any way to flag anything in the chain to
stop. The only check is a method in Cookie.pm
called
cookie_is_rejecting
which just compares the configured cookie path to
the request path.
So, it looks like the best way to do this is to add my own override to
either update_session_cookie
or cookie_is_rejecting
. I think I'll
use cookie_is_rejecting
.
Here is the code I finally used. Note that this is rather klugy, but it works...
package Catalyst::Plugin::Session::State::Cookie::Sanity;
use base qw/Catalyst::Plugin::Session::State::Cookie/;
use MRO::Compat;
use strict;
sub cookie_is_rejecting {
my ($c, $cookie) = @_;
($c->stash->{cache_control_time} // 0) > 0
or $c->maybe::next::method( $c, $cookie );
}
1;