본문 바로가기

프로그래밍 언어 노트/Clojure

[clojure] clj-oauth2 를 통해서 github Oauth 를 가져와 보자

주요 코드

(ns ossss.routes.oauth
  (:require
    [ossss.config :refer [env]]
    [mount.core :refer [defstate]]
    [clj-http.client :as http]
    [clj-oauth2.client :as oauth2]
    [ring.util.http-response :as response]))


;; env 에 있는값을 쓰기 위해서 defstate 사용
(defstate github-oauth2 :start
  {:authorization-uri (env :authorize-uri)
   :access-token-uri (env :access-token-uri )
   :redirect-uri "http://localhost:3000/oauth/callback"
   :client-id (env :oauth-consumer-key)
   :client-secret (env :oauth-consumer-secret)
   :access-query-param :access_token
   :scope ["user:email"]
   :grant-type "authorization_code"
   :access-type "online"
   :approval_prompt ""})

;; 위 github-oauth2 맵으로부터, code 를 가져오는 URI 를 생성한다.
;; github-oauth2 가 (status 라 lazy 하게 하기위해서 함수로 했음)
(defn auth-req []
  (oauth2/make-auth-request github-oauth2))

;; 위 auth-req의 URI 를 Get 으로 보내면
;; resp 가 callback 으로 오는데,  여기의 params 값이 code 내용이다
;; code로부터 access-token 을 가져온다.
(defn- github-access-token [params]
  (oauth2/get-access-token github-oauth2 params (auth-req)))

;; 콜백 api 를 이 함수로 연결해야함
(defn oauth-callback
  [{:keys [session params]}]
  (println session)
  (println params)
  (if (:denied params)
    {:status 200, :body "nok"}
    {:status 200, :body (if-let [access-token (github-access-token params)]
                          (do (println access-token)
                              (http/get "https://api.github.com/user/public_emails" {:oauth-token (:access-token access-token)})
                              ;; access-token 이 있으니까 이걸 oauth-token 에 넣고 원하는 api 를 쓰면된다
                              ;; 여기서 clj-oauth2.client의 get 을 쓰지 않은 이유가... 
                              ;;왠지 모르겠는데 아예 헤더에 토큰이 안들어가서 request token 응답이옴..
                              ))}))

사용하는 로직은 Oauth 검사를 하기위하여 대충 해놨는데 흐름만 보면된다.

code 요청하는 URI 생성 -> URI 로 접속 -> 리다이렉트됨 -> 리다이렉트 될때 code 가 같이 들어오는데 이걸로 엑세스 토큰 요청 -> 엑세스토큰을 헤더에 넣어서 원하는 정보 요청 (여기서는 email)

 

사용 클라이언트

DerGuteMoritz/clj-oauth2: OAuth 2.0 implementation for Clojure (github.com)

 

DerGuteMoritz/clj-oauth2

OAuth 2.0 implementation for Clojure. Contribute to DerGuteMoritz/clj-oauth2 development by creating an account on GitHub.

github.com

Oauth2 를 이용하기 위한 클라이언트

 

발생한 문제...

문제는 원래
access-token 을 얻은다음에 (oauth2/get "https://api.github.com/user/public_emails" {:Oauth2 access-token}) 로 얻는것같은데.....

토큰이 이 헤더에 안들어간다.. 이유를 모르겠다.. 거의 3시간을 씨름했는데.. 도저히 안되서 그냥 clj-http 이용해서 oauth-token 을 넣어주었다.

-> 정확하지는 않지만, 내부코드를 디버깅해보면

header 가 아닌 query-param 에 넣어서 그런듯하다.. (assoc-in 참고)

2016년이 최신 커밋인 마이너의 한계인거 같기도하고...

그래도 Uri 흐름만 알아도 Oauth 는 대충 이해한거니까 (?) 나중에는 그냥 Http client 만으로 바꾸는게 좋을듯하다..

728x90