Skip to content

Instantly share code, notes, and snippets.

@ikitommi
Last active December 1, 2022 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ikitommi/cd0fe42240fa97cee12fff2ef0055b31 to your computer and use it in GitHub Desktop.
Save ikitommi/cd0fe42240fa97cee12fff2ef0055b31 to your computer and use it in GitHub Desktop.
Fetch + Clojure/Script

Given

  • local development, FE (3008) & BE (6047) running in separate ports
  • want to send and read cookies over fetch, BE sets, FE sends, http-only
  • in real environments, CORS is handled in api-gateway, so just need local CORS solution here

Solution

  1. fetch needs to have :credentials set to "include" (different ports, "same-origin" doesn't seem to work)
  2. because of 1, the local CORS can't have wildcards, you need list all possible headers, origins etc.
  3. also need to set "Access-Control-Allow-Credentials" to "true" in BE cors config
  4. and the cookie domain should be localhost, while allowed origin is http://localhost:3008

Code

Frontend

(-> (vf/fetch {:uri "http://localhost:6047/sso/info"
               :method :get
               :credentials "include" ;; this is needed
               :headers {"Authorization" (str token-type " " token)}})
    (.then save-info))

Backend

(defn wrap-local-cors [handler]
  (let [with-cors (fn [request response]
                    (-> response
                        (update
                         :headers
                         merge
                         {"Access-Control-Allow-Origin" (get-in request [:headers "origin"])
                          "Access-Control-Allow-Methods" "GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS"
                          "Access-Control-Allow-Credentials" "true"
                          "Access-Control-Allow-Headers" "...list all here..."})))
        preflight-response {:status 200, :body "preflight complete"}
        preflight (fn [handler request]
                    (if (= :options (:request-method request))
                      (fn
                        ([request] (with-cors request preflight-response))
                        ([request respond _] (respond (with-cors request preflight-response))))
                      handler))]
    (fn
      ([request] (with-cors request ((preflight handler request) request)))
      ([request respond raise] ((preflight handler request) request (comp respond (partial with-cors request)) raise)))))

... setting the cookies:

  • add ring.middleware.cookies/wrap-cookies into the pipeline and set the cookie with:
{:status 200
 :body body
 :cookies {"kikka" {:value "kukka6"
                    :http-only "true"
                    :domain "localhost"}}}

Good reads

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment