Re: Cookie help, anyone?
James Fleming <lisp <at> electronic-quill.net>
2006-03-11 04:21:26 GMT
Let's try this again, from the address that's actually subscribed to the
list. *facepalm* How did I manage to learn to type, again?
> I'm new to the list, and I'm using cl-ajax/araneida/sbcl for a webapp. I'm at
> the point where I need authorization, and I'm not sure where to start.
Hi, Jonathon. I'm about to implement authorization in
apache/araneida/sbcl myself, but have the headstart of having done it in
other environments first. The bad news is that there are all sorts of
ways of doing it; the good news is that at least one of them should be
suited to what you need.
> I really only know enough http to get by. I'm not quite sure how the handler
> classes access cookies, and when.
As Alan mentioned, the (request-cookie <request> <cookie-name>) method
will do that for you.
> I'm hoping someone could help me set up a
> handler that on each file request, checks a cookie. At least, I think that's
> what I want.
Easy done:
(defmacro with-cookies (&body body)
"Cookie-handling macro to save even more typing"
`(let ((received-cookie (request-cookie request "session")))
(setf received-cookie (set-cookie-if-needed received-cookie
request))
, <at> body))
In this case, I'm retrieving a cookie called "session", and setting it
if it's absent. (set-cookie-if-needed) is a function of my own devising
which does what it sounds, but also does a bunch of housekeeping while
it's at it, so is a fraction too involved to post to the list. Unless,
of course, everybody really wants to laugh at my approach to
implementing a shopping cart.
What I do to make use of the cookie's value is wrap the handler method
in (with-cookies ), and refer to received-cookie when I want to check
their session ID. E.g:
(defmethod handle-request-response ((handler checkout)
(method (eql :post))
request)
(with-cookies
<method body goes here>))
The housekeeping stuff in (set-cookie-if-needed) checks whether they
already have a valid session, kills it if it's too old, and sets a new
cookie if necessary, storing it in the database on the way. It's amazing
how complex it can all get and how quickly. It's equally amazing a)how
compactly you can do it in lisp, and b)how fraggin' steep the learning
curve can be. Satisfying, though.
As an aside, I realised recently that I seemed to be encountering
nothing but frustration in writing this app; every time I tried to add a
new kind of functionality, there'd be a new puzzle to solve. Now, I love
puzzle-solving, which is why I play with these things, but it was
frustrating that I hadn't yet managed to implement a section entirely
with stuff I already knew. Eventually, I realised that once I'd figured
out how to do something, I'd thereafter do it so quickly and easily that
I just didn't notice doing it. The language itself is just naturally
almost frictionless.
For setting a cookie:
(request-send-headers request
:set-cookie (list (cookie-string <name> <value>
:max-age <maximum age in seconds>
:domain <your domain goes here>)))
There are other attributes you can set, and neither of those are
madatory, iirc; they're just useful to me. This, of course, is at the
heart of (set-cookie-if-needed).
Just what kind of authorization system will suit you depends on exactly
what you need, though. Is it for the whole site? Certain functions?
Condition-dependent? Just certain sub-trees of the site? Do you have
apache in front of araneida? Do all users get the same access, or do you
need to grant different things to different user IDs?
I don't mean to intimidate with this; rather, I'll be happy to help you
zero in on what you need. My dayjob is e-commerce platform support for a
faceless megacorporate, so I've seen a stack of different ways of
securing things; some of them even seem to work :)
HTH,
James
--
--
Stupidity killed the cat.
Curiosity was framed.
_______________________________________________
lispweb mailing list
lispweb <at> red-bean.com
http://www.red-bean.com/mailman/listinfo/lispweb