Skip to content

Instantly share code, notes, and snippets.

@shaharz
Created January 27, 2014 16:47
Show Gist options
  • Save shaharz/8652256 to your computer and use it in GitHub Desktop.
Save shaharz/8652256 to your computer and use it in GitHub Desktop.
Twitter/OAuth workflow for Friend
(ns friend-oauth
(:require
[cemerick.friend :as friend]
[cemerick.friend.workflows :refer [make-auth]]
[clj-http.client :as client]
[oauth.client :as oauth]
[ring.util.request :as request]))
(defn- which-oauth-uri
[config request]
(condp = (request/path-info request)
(get-in config [:client-config :callback :path]) :callback
(:login-uri config) :login
(-> request ::friend/auth-config :login-uri) :login
nil))
(defn- default-credential-fn
[creds]
{:identity (:access-token creds)})
(defn- handle-login [consumer config request]
(let [{{{:keys [domain path]} :callback} :client-config} config
callback-uri (str domain path)
;; Step 1: Obtaining a request token
request-token (oauth/request-token consumer callback-uri)]
;; Step 2: Redirecting the user
(-> (oauth/user-approval-uri consumer (:oauth_token request-token))
ring.util.response/redirect
;; Store request token for step 3
(assoc-in [:session :request-token] request-token))))
(defn- handle-callback [consumer config request]
(let [;; Upon a successful authentication, your callback_url would receive a request containing the oauth_token and oauth_verifier parameters.
{{request-token :request-token} :session
{oauth-token :oauth_token verifier :oauth_verifier} :params} request]
;; Your application should verify that the token matches the request token received in step 1.
(when (= oauth-token (:oauth_token request-token))
;; Step 3: Converting the request token to an access token
(let [access-token (oauth/access-token consumer request-token verifier)]
(when-let [auth-map ((:credential-fn config default-credential-fn) {:access-token access-token})]
(make-auth auth-map
{::friend/workflow :oauth
::friend/redirect-on-auth? true}))))))
(defn workflow
"Workflow for Twitter/OAuth"
[config]
(let [client-config (:client-config config)
uri-config (:uri-config config)
consumer (oauth/make-consumer
(:client-id client-config)
(:client-secret client-config)
(:request-uri uri-config)
(:access-uri uri-config)
(:authorization-uri uri-config)
:hmac-sha1)]
(fn [request]
(case (which-oauth-uri config request)
:login (handle-login consumer config request)
:callback (handle-callback consumer config request)
nil))))
(def ^:private twitter-uri-config
{:request-uri "https://api.twitter.com/oauth/request_token"
:access-uri "https://api.twitter.com/oauth/access_token"
:authorization-uri "https://api.twitter.com/oauth/authenticate"})
(def ^:private twitter-client-config
{:client-id (env :twitter-consumer-key)
:client-secret (env :twitter-consumer-secret)
:callback {:domain "http://localhost:3000" :path "/auth/twitter/callback"}})
(friend-oauth/workflow
{:login-uri "/auth/twitter/"
:client-config twitter-client-config
:uri-config twitter-uri-config
:credential-fn twitter-credential-fn})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment