-
I am setting Cache-Control headers with Vary: Cookie, but the problem is that a new cookie is sent for each response. There's no reason to send a new cookie for each response, since the cookies in this application have a relatively long expiration time. What I would like to do is track when the session data is changed, and only send a cookie when there is a change. Is there a practical way to do this without writing a custom session handler? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 5 replies
-
This seems to be caused by updating the I can see where this is necessary when the session isn't stored in a cookie. But when storing session data in the cookie, keeping a separate expires key is unnecessary because the browser will drop the cookie when it expires. Updating the cookie for every request means that the cookie cannot be used for cache control. Now that I've been experimenting with various solutions, I think the best solution may be to write a custom serializer for the session that ensures a consistent expiration. |
Beta Was this translation helpful? Give feedback.
-
I have a hook that sets a static expiration time: use Time::Seconds qw/ ONE_MINUTE ONE_HOUR /;
...
$self->hook( after_dispatch => sub($c) {
if ( is_success( $c->res->code ) ) {
# Mojolicious::Sessions will always update the session
# time to `expiration` + current time, unless there is an
# explicit `expires`. But `expires` must be set for each
# session, otherwise Mojolicious::Sessions will update it
# on every request.
my $session = $c->session;
unless (defined $session->{expires}) {
my $window = 15 * ONE_MINUTE;
$session->{start} ||= time;
$session->{expiration} ||= ONE_HOUR;
$session->{expires} = $session->{start} + $session->{expiration};
# If were are near the expiration time, then reset the
# start time.
if (($session->{expires} - $window) <= time) {
$session->{start} = time;
$session->{expires} = $session->{start} + $session->{expiration};
}
}
$c->res->headers->cache_control("private, max-age=" . ONE_HOUR);
$c->res->headers->vary('Cookie');
}
} ); Note that the application I am writing this for is not concerned about replay attacks. Users log in and have read-only access to their data. But the application can put an extra load on the databases. So caching pages is important. |
Beta Was this translation helpful? Give feedback.
-
I think a cleaner alternative will be to simply move the cache store to a server-based store, so that the cookie only contains a session id. |
Beta Was this translation helpful? Give feedback.
I think a cleaner alternative will be to simply move the cache store to a server-based store, so that the cookie only contains a session id.