Archive for June, 2012

Facebook with Hunchentoot and OAuth2

June 28, 2012

This is a quick and dirty to see how you can access Facebook stuff from Hunchentoot.

You will need Hunchentoot, Drakma, cl-who and cl-json to run this code. All of them can be gotten with Quicklisp.

You will also need a valid domain that points to localhost to test this code on your local machine. I just set up a subdomain on one of my servers that points to 127.0.0.1. If you don’t have access to your own domain server use localtunnel.com or something like it. What ever domain you decide on remember to set the site url in your Facebook app settings to the same domain.

When you want to access Facebook resources you need an access token and to get an access token you have to take the user to a facebook page that asks the user to log in and to give access to your app. Once the user has given access or denied access facebook redirects the user back to the callback uri that you specified, bringing them back to your web page.

If you look at the code you will see that we first get an access code from /dialog/oauth and then a token from /oauth/access_token, this is because we are using response_type=code. The reason we don’t use response_type=access_token is because what Facebook returns can’t be accessed by hunchentoot only javascript can get hold of the stuff after the # that is returned where you would expect a querystring.

Once we have an access token we fetch trivial data form Facebook for the user that authenticated.

The following code is not pretty but it is as short as I could get it without confusing the issues at hand.

There are various OAuth implementations for Common Lisp but if you are reading this you might have struggled with those and hopefully this code will help to clarify what is going on in those more involved implemetations of OAuth. (And none of them had Facebook examples that I could find.)

(define-easy-handler (callback :uri "/callback") ()
  (if (not (parameter "code"))
    (with-html-output-to-string (*standard-output*)
      ;;Clicking on this link will get you an access code, if the user approves.
      (:a :href "https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&response_type=code
                  &redirect_uri=http://A_VALID_DOMAIN_THAT_POINTS_TO_LOCALHOST:8000/callback" 
               (str "Go Facebooking")))
    (multiple-value-bind (body status)
        ;;Use the access code to get a access token.
        (drakma:http-request 
         (format nil "https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID
                       &redirect_uri=http://A_VALID_DOMAIN_THAT_POINTS_TO_LOCALHOST:8000/callback
                       &client_secret=APP_SECRET=~A" 
                 (parameter "code")))

      ;;Check if all was well.
      (if (equal status 200)
          (let* ((querystring (split-string body #\&))
                 (access-token (split-string (first querystring) #\=))
                 ;;(expiry (split-string (second querystring) #\=))
                 )

            ;;Fetch something interesting with your access token.
            (multiple-value-bind (bodyx)
                (drakma:http-request 
                 (format nil "https://graph.facebook.com/me?access_token=~A" 
                         (second access-token)))
                (format nil "~A" (json::decode-json-from-string bodyx))))
          (format nil "Something went wrong:~%~A"
                  (json::decode-json-from-string body))))))

(defun split-string (string char)
    "Returns a list of substrings of string divided by char."
    (loop for i = 0 then (1+ j)
          as j = (position char string :start i)
          collect (subseq string i j)
          while j))

SBCL glibc Error on Ubuntu

June 15, 2012

I use Ubuntu and SBCL for all my lisp development but lately the latest versions of the two have not been playing nicely with each other.

This will effect some of the instructions to install SBCL in my other blogs.

To get around the problem install sbcl in the following manner:

sudo apt-get install build-essential
sudo apt-get install sbcl
sudo apt-get install time
wget http://sourceforge.net/projects/sbcl/files/sbcl/1.0.57/sbcl-1.0.57-source.tar.bz2
bzip2 -cd sbcl-1.0.57-source.tar.bz2 | tar xvf -
cd sbcl-1.0.57-source
sudo sh make.sh
sudo apt-get remove sbcl
sudo sh install.sh

To test SBCL:
/usr/local/bin/sbcl

WFX, XDB2 – Open sourced

June 15, 2012

Most of what I do is web based systems in Common Lisp using Hunchentoot. Over time me and some of my collueges have created one or two packages to help us with this type of development. Some of these we always wanted to open source but never got round to it because we have not had the time to do decent documentation (something of a pet pieve of mine).

However we came to a point where we felt that despite the lack of documentation these packages would be of use to other lispers, so we took the plunge and opened up WFX and XDB2 to the public. Both have a BSD 2 clause license so what and how you do anything with them is your problem.

WFX is a widget framework written for use with Hunchentoot.

XDB2 is a collection of interfaces that you can use as a in memory persistable transaction log with snapshots.

(As time permits I will blog more about these packages, but don’t hold your breath, time has been in short supply this year so far.)