Siscia Tech

Programming, tech related blog

1 note &

Login with Facebook clojure/java

I spend a couple of days trying to implement OAuth2 (aka Login with -{facebook, twitter, google, & more}) in clojure when I finally gave up.

There are several libraries out there but honestly I don’t like any of those, or they don’t work.

Even worse I didn’t find any patter to follow, even if I didn’t look very careful and this is why I am writing this micro-post.

First of all I am gonna use a java library, scribe it’s looks like it is widely used in the java community but I didn’t know its existence before, its look like an amazing library for OAuth and I didn’t spend to much time experimenting at the REPL thanks to the amazing documentation and examples.

Ok, let’s go into something more interesting, how “Login with Facebook” works ?

First of all you need to make an app on facebook, it’s not difficult, remember to put the real domain when they ask for, the App ID and the App Secret are very important but they won’t go away so…

Then it’s pretty simple, your user click the button and you redirect him to an URL that FB gave to you which lead to the FB page where the user can login in facebook and authorized the app, when everything is done, so the user has authorized your app, facebook re-direct the user to your domain in a specific URL passing via GET a huge string, now you exchange that string with a token and finally the token with the info that you need, stuff like name, email, where the user live and more — a lot more even if I asked only the basic information.

Ok, I am boring… Let’s go straight to the code:

The model

(ns morgan.models.social

  (:require [clj-http.client :as client])

  (:import [org.scribe.oauth OAuthService]

           [org.scribe.builder ServiceBuilder]

           [org.scribe.model Token Verifier OAuthRequest Verb])

  (:import [org.scribe.builder.api FacebookApi TwitterApi]))

(def facebook-service

  (-> (doto

          (ServiceBuilder.)

        (.provider (FacebookApi.))

        (.apiKey “your api key”)

        (.apiSecret “your api secret”)

        (.callback “URL where FB is gonna re-direct your user”))

      (.build))) ;;It’s necessary to call .build outside the doto,

;;otherwise we would get a ServiceBuilder and not a OAuthService…

(def facebook-url

  (.getAuthorizationUrl facebook-service nil))

(defn get-info-facebook [code]

  (let [verifier (Verifier. code)

        token (.getAccessToken facebook-service nil verifier)

        request (OAuthRequest. (Verb/GET) “https://graph.facebook.com/me”)]

    (do

      (.signRequest facebook-service token request))

    (.getBody (.send request))))

and the view:
(ns morgan.views.social
  (:use [noir.core :only [defpage]]
        [noir.response :only [redirect]]
        [morgan.models.social]))
(defpage “/facebook” []
   (redirect facebook-url))
(defpage “/fb” {:keys [code]}
   (get-info-facebook code))
That’s it, nothing hard, isn’t it ?
In the model: 
The var called facebook-service is the core, it is an object that take care of everything, you just need to pass it what service are you gonna use, your App ID, your App Secret, and the url when the user is going to be redirect.
facebook-url is the url that the user need to follow in order to login into facebook and to authorize the app, should be behind a “LogIn with Facebook” button.
The last function let you get the info from the user’s facebook account, the function return a string of the json that facebook send, you may want to parse it with chesmire or something similar and then store the information.
In the view:
The page /facebook is pretty pointless, I was simply to lazy to add a button, it, anyway, redirect the user to the facebook-url page where the user can authenticate and authorize your app.
After that everything went smoothly the user is redirect by facebook in the /fb page with the code via GET (where the user is redirect depends on what you said in the .callback when you are creating the facebook-service object); the page get the code, call the proper function and show back what I got from facebook about the user, pretty straight.
You can check everything here https://morgan-siscia.rhcloud.com/facebook 
Please be aware: 
right now I am NOT saving any of your information.
Hope you enjoy the reading
Simone Mosciatti
PS: Since you are please check this out https://morgan-siscia.rhcloud.com and let me know what you think.

Filed under clojure facebook sign in with login login with facebook

  1. zerosumz reblogged this from sisciatech
  2. sisciatech posted this