-
-
Save stijnopheide/af90400b26a686e1145b9a5e2f0a2874 to your computer and use it in GitHub Desktop.
yada + lacinia + cookie auth
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def cookie-authentication | |
{:realm realm | |
:authentication-schemes [{:verify (fn [{:keys [:my/db cookies] :as ctx}] | |
(when-let [session-cookie (get cookies session-cookie-name)] | |
(verify-session db session-cookie)))}]}) | |
(defn add-session-cookie | |
[defaults] | |
(fn [{:keys [::session] :as ctx}] | |
(if session | |
(assoc-in ctx [:response :cookies session-cookie-name] (create-session-cookie defaults session)) | |
ctx))) | |
(defn cors-access-control | |
[{:keys [allow-origin]} methods] | |
{:allow-headers #{"Content-Type"} | |
:allow-credentials true | |
:expose-headers #{} | |
:allow-methods methods | |
:allow-origin (cond | |
(string? allow-origin) | |
(fn [{:keys [request] :as ctx}] | |
(when-let [origin (get-in request [:headers "origin"])] | |
(when (re-find (re-pattern allow-origin) origin) | |
origin))) | |
:else allow-origin)}) | |
(defn execute-query | |
[ctx variables parsed-query] | |
(let [resolver-result (lacinia/execute-parsed-query-async parsed-query variables ctx) | |
result (md/deferred)] | |
(lacinia.resolve/on-deliver! resolver-result | |
(fn [x] | |
(md/success! result x))) | |
result)) | |
(defn execute-query-and-create-response | |
[ctx schema query variables operation-name] | |
(md/let-flow [parsed-query (parse-query schema query operation-name)] | |
(execute-query ctx variables parsed-query))) | |
(defn parse-query-from-json | |
[ctx] | |
[(get-in ctx [:parameters :body :query]) | |
(get-in ctx [:parameters :body :variables]) | |
(get-in ctx [:parameters :body :operationName])]) | |
(defn graphql-resource | |
[schema auth] | |
(yada/resource | |
{:produces | |
#{"application/json"} | |
:methods | |
{:post | |
{:parameters {:body s/Any | |
:query {(s/optional-key :variables) String | |
(s/optional-key :query) String | |
(s/optional-key :operationName) String}} | |
:produces #{"application/json" "application/json; charset=utf-8"} | |
:consumes #{"application/json" "application/graphql"} | |
:response (fn [ctx] | |
(let [[query variables operation-name] | |
(case (get-in ctx [:request :headers "content-type"]) | |
"application/json" (parse-query-from-json ctx) | |
"application/json; charset=utf-8" (parse-query-from-json ctx) | |
"application/graphql" [(or (get-in ctx [:parameters :query :query]) | |
(get-in ctx [:parameters :body])) | |
(json/parse-string (get-in ctx [:parameters :query :variables]) true) | |
(get-in ctx [:parameters :query :operationName])])] | |
(execute-query-and-create-response ctx schema query variables operation-name)))} | |
:get | |
{:parameters {:query {:query String | |
(s/optional-key :variables) String | |
(s/optional-key :operationName) String}} | |
:response (fn [ctx] | |
(execute-query-and-create-response ctx | |
schema | |
(get-in ctx [:parameters :query :query]) | |
(json/parse-string (get-in ctx [:parameters :query :variables]) true) | |
(get-in ctx [:parameters :query :operationName])))}} | |
:access-control | |
(merge (ors-access-control (:cors auth) #{:post :get}) | |
cookie-authentication) | |
:interceptor-chain | |
(-> yada/default-interceptor-chain | |
(util.yada/insert-interceptor | |
yada.interceptors/create-response | |
(add-session-cookie (:session-cookie auth)))) | |
:responses | |
responses})) | |
(defn login-response | |
[ctx [session cookies]] | |
(assoc (:response ctx) | |
:body (whatever-you-need-from session) | |
:cookies cookies)) | |
(defn login | |
[auth] | |
(yada/resource | |
{:methods | |
{:post {:parameters {:body {:token String}} | |
:response (fn [ctx] | |
(md/chain (do-your-login-with-whatever-you-need-from-the-request-and-give-back-a-session-cookie (get-in ctx [:parameters])) | |
(fn [result] | |
(login-response ctx result)))) | |
:produces #{"application/json"} | |
:consumes #{"application/json"}}} | |
:access-control | |
(auth/cors-access-control (:cors auth) #{:post}) | |
:responses | |
responses})) | |
(defn routes | |
[auth] | |
["" | |
[["/login" (login auth)] ;; some resource that sets the cookies properly | |
["/graphiql" (yada.resources.classpath-resource/new-classpath-resource "public/graphiql" ;; graphiql downloaded and installed in resource folder | |
["/graphql" (graphql-resource graphql auth)]]]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment