clack
clack copied to clipboard
Clack.Middleware.Session creates a session every time
Hi,
If I wrap
my app with Clack.Middleware.Session
, a session is created for each user. Even if the user hasn't logged in, through any way.
Maybe I have missed something? If I haven't, then it's problematic.
The problem with this approach is that it's not compatible with reverse proxy cache solutions like varnish. A good way to use varnish, for example, is to cache pages and serve the same cache entry for all the anonymous users. To know that a user is anonymous, it just looks at the request cookies and see if no session cookie is present.
2 new methods could be added on the middleware: start
and destroy
. start
would basically create the session cookie and hash table, and destroy
would remove the session cookie and delete the associated data.
This way, the methods could be called manually in the route handlers, for example at login and logout time.
To maintain backwards compatibility, a new option could be added to the constructor.
Cheers, Florian
Clack.Middleware.Session adds a key :clack.session.options
to env
. It is a hash-table to communicate with the middleware.
It sees these keys -- :expire
, :change-id
and :no-store
.
You should be able to prevent storing a session by (setf (gethash "no-store" (getf env :clack.session.options)) t)
.
(builder
(lambda (app)
(lambda (env)
(prog1 (call app env)
(unless (logined-p)
(setf (gethash "no-store" (getf env :clack.session.options)) t)))))
<clack-middleware-session>
app)
... but it may be wrong with the code. I'm looking into it.
Well, I want to store the session at some point. Just... being able to start and stop the storing. And send the matching cookies...
The middleware would be better to have an option for preventing sending "Set-Cookie" header if the session is empty. Doesn't it suit your case?
Well, if I can create the session (and clack will send the set-cookie), and destroy it (and clack will send the set-cookie), then yes, it suits my case.
I'm not sure I completely understood what you said, but here is the ideal scenario:
- Clack starts, no session created.
- My code does
(clack.session.start)
or something similar:- the
*session*
hash-table has a new entry - a set-cookie header is sent to add the sessionid=id pair
- the
- My code does
(clack.session.destroy)
or something similar:- the
*session*
hash-table loses an entry - a set-cookie header is sent to remove the sessionid pair
- the
Is that what you had in mind?
I think it would be nice if it doesn't send Set-Cookie header when "no-store" is non-NIL. However, I'm not willing to change the default behaviour from "I'm setting it to every request" to "I'll set it if you tell me".
Needless to say, but you can write your own session management middleware to do it.
It would be really helpful if the Set-Cookie header was missing when the session is empty. As there is the cookie law in EU, we need to ask before setting any cookies. This compliance becomes easy when the first cookie set by default is the acceptance of the use of cookies and not the arrival to the site. The acceptance of the use of cookies can also be made implicit by simply showing a message that the site uses cookies and by using functions requiring cookies, the user accepts the use of cookies. However, the acceptance can not occur before this text is displayed.
How can I do this?
@tsill European law doesn't ban all cookies if no consent is asked or provided. Session management and similar are not subject of this law. Please compare with: http://ec.europa.eu/ipg/basics/legal/cookies/index_en.htm
Clack v1 is deperecated. Lack is a successor of it.
Lack.Middleware.Session has :keep-empty
option for choosing if sending the Set-Cookie
header when the session is empty. (Default is T
)