주요 코드
(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)
Oauth2 를 이용하기 위한 클라이언트
발생한 문제...
문제는 원래
access-token 을 얻은다음에 (oauth2/get "https://api.github.com/user/public_emails" {:Oauth2 access-token}) 로 얻는것같은데.....
토큰이 이 헤더에 안들어간다.. 이유를 모르겠다.. 거의 3시간을 씨름했는데.. 도저히 안되서 그냥 clj-http 이용해서 oauth-token 을 넣어주었다.
-> 정확하지는 않지만, 내부코드를 디버깅해보면
2016년이 최신 커밋인 마이너의 한계인거 같기도하고...
그래도 Uri 흐름만 알아도 Oauth 는 대충 이해한거니까 (?) 나중에는 그냥 Http client 만으로 바꾸는게 좋을듯하다..
728x90
'프로그래밍 언어 노트 > Clojure' 카테고리의 다른 글
Clojure 의 매크로 시스템의 튜링완전 (애매한) 증명 feat SKI (0) | 2024.07.14 |
---|---|
[Clojure] Clojure 에서 Runtime 함수를 생성해보자 (0) | 2021.06.30 |
[Clojure/Luminus] Luminus + Intellij 시작 설정 (0) | 2021.05.11 |
[Clojure] Idiomatic Clojure - Code Smells (관용적인 클로저 - 코드 스멜) (0) | 2021.01.18 |
[Clojure] Clojure Reactive 와 Clojure CSP(clojure.async) (0) | 2020.12.17 |