Monday, April 30, 2018

Facebook Sign-in using Clojure

In order to provide Facebook sign-in functionality you need to create a new Facebook App from this url: https://developers.facebook.com/docs/facebook-login. Provide the redirection URI that you’ll use for the App. After setting up the app you’ll get an App ID and App Secret key.



We’ll use “clj-oauth2.client” to redirect a user to the authentication page, “clj-http.client” for HTTP requests, “cheshire.core” to parse Json string in order to get keywords, “noir.respose” to provide re-directions and “compojure.core” for routing.
We’ll begin with defining a new namespace:
1
2
3
4
5
6
(ns exampleapp.routes.facebook
 (:use compojure.core)
 (:require [clj-oauth2.client :as oauth2]
           [noir.response :as resp]
           [clj-http.client :as client]
           [cheshire.core :as parse]))

In facebook namespace define an atom, facebook-user, to store Facebook user details:
1
2
(def facebook-user
  (atom {:facebook-id "" :facebook-name "" :facebook-email ""}))

Now include the App ID and App Secret key you just got after creating a new Facebook app along with the redirection URI, in the code below:
1
2
3
(def APP_ID "your app id")
(def APP_SECRET "your app secret key")
(def REDIRECT_URI "http://localhost:3000/auth_facebook")

and define an oauth2 map containing all the details required for Facebook log in:
1
2
3
4
5
6
7
8
9
(def facebook-oauth2
 {:authorization-uri "https://graph.facebook.com/oauth/authorize"
  :access-token-uri "https://graph.facebook.com/oauth/access_token"
  :redirect-uri REDIRECT_URI
  :client-id APP_ID
  :client-secret APP_SECRET
  :access-query-param :access_token
  :scope ["email"]
  :grant-type "authorization_code"})

We can use “make-auth-request” function defined in “clj-oauth2.client” library to get the redirect URI on which the user should be redirected. The user can now give access to the app we created in first step.

1
2
(resp/redirect
  (:uri (oauth2/make-auth-request facebook-oauth2)))

Note that we used noir.response/redirect function to provide the redirection.
After a Facebook user grant access to the app, we’ll get a response containing access token on the redirection URI we provided while setting up our Facebook app. We’ll use “compojure.core’s” GET to get the response:

1
2
(defroutes facebook-routes
 (GET "/auth_facebook" {params :query-params} (facebook params)))

and pass it to a function in order to get the access token and user details.
We’ll use the code below for getting access token and user details:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
(defn facebook [params]
 (let [access-token-response (:body (client/get (str "https://graph.facebook.com/oauth/access_token?"
                                                     "client_id=" APP_ID
                                                     "&redirect_uri=" REDIRECT_URI
                                                     "&client_secret=" APP_SECRET
                                                     "&code=" (get params "code"))))
       access-token (get (re-find #"access_token=(.*?)&expires=" access-token-response) 1)
       user-details (-> (client/get (str "https://graph.facebook.com/me?access_token=" access-token))
                        :body
                        (parse/parse-string))]
  (swap! facebook-user
   #(assoc % :facebook-id %2 :facebook-name %3 :facebook-email %4)
     (get user-details "id")
     (get user-details "first_name")
     (get user-details "email"))))

This article was first published on the Knoldus blog.

No comments:

Post a Comment