2
votes

(I use Hunchentoot and Restas, just thought that I would mention it up here too)

I don't really know how to do this stuff in general with HTTP, so I thought that maybe posting my code would be the simplest way to show my intent:

(define-route log-in ("/log-in/" :method :post)
  (multiple-value-bind (username pwd) (hunchentoot:authorization)
    (cond ((and (nth-value 1 (gethash username *users*)) ;; User exists
                (string= pwd (gethash username *users*)))) ;; Password is correct
          ;; Do something to keep track of logged in user
          )))

I basically just want to let a user log in, give him some sort of way to say "hey, it's me again" and some sort of way for me to say "Oh, hey! It is you again, here you go" and then serve the user a webpage. I think that this should be done with cookies along with simply storing some value in a list that can be checked against the cookie.

How am I supposed to do this properly with Hunchentoot+Restas? Code and some explanation would be really awesome, I'm pretty lost here.

1

1 Answers

2
votes

You might want to use (start-session) and then add a method like:

(defmethod handle-request :before ((acceptor acceptor) (request request))
   (unless (your-check-request-matches-login-page) ; skip session check on login page
       (if (null *session*)
          (redirect "/log-in")
          (progn
             (your-check-session-validity)
             (other-stuff)))))

The above method will work if you need to do authentication with a login page. But you need another way to get user and password from the user, as (authorization) will give you what the browser sent in the headers, and that is for basic-auth.

If you do really want to use basic-auth, then the browser will take care of poping-up a dialog to ask the user for credentials, so you don't need a login page. You need the following method, to intercept all requests and send the apropriate headers:

(defmethod handle-request :before ((acceptor acceptor) (request request))
    (multiple-value-bind (username pwd) (hunchentoot:authorization)
        (if (and (nth-value 1 (gethash username *users*)) ;; User exists
                 (string= pwd (gethash username *users*))) ;; Password is correct
            (progn
                ;; Do something here
            )

            (require-authorization "realm"))))