How to configure yada to allow cross-origin requests (Clojure)?

182 views Asked by At

I have a yada resource configured as below:

(yada/resource
    {:methods {:get
               {:produces "text/plain"
                :response (fn [ctx]
                            "Hello world!!")}}})

and a curl -i localhost:8080/api/new returns:

HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Length: 13
Content-Type: text/plain
Server: Aleph/0.4.4
Connection: Keep-Alive
Date: Thu, 12 Dec 2019 18:50:42 GMT

Hello world!!

But when I add the access-control configuration to allow origin:

(yada/resource
    {:methods {:get
               {:produces "text/plain"
                :response (fn [ctx]
                            "Hello world!!")}}
     :access-control {:allow-origin "*"}})

I don't see the additional header:

HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Length: 13
Content-Type: text/plain
Server: Aleph/0.4.4
Connection: Keep-Alive
Date: Thu, 12 Dec 2019 18:52:32 GMT

Hello world!!

I have also tried using the example found at https://juxt.pro/yada/manual/index.html#cross-origin-resource-sharing-cors but have the same results.

And I am seeing the dreaded Access to resource at ... from origin ... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource when I try to access the endpoint from my UI.

What am I missing in this config?

2

There are 2 answers

0
Jeremy Field On

I think your config is correct (with the usual provisos about allowing "*"). I think yada doesn't actually make the headers unless the request has an Origin header:

(defn access-control-headers [ctx]
  (if-let [origin (get-in ctx [:request :headers "origin"])]
    ;...

This might account for the difference between your curl invocation and your actual client. Try using curl -H "Origin: http://origin" -vi http://server/endpoint to inspect.

0
KByrne On

I was able to use the following workaround:

(yada/resource
    {:methods {:get
               {:produces "text/plain"
                :response (fn [ctx]
                            (let [response (:response ctx)
                                  updated-response (assoc-in response [:headers] {"Access-Control-Allow-Origin" "*"})]
                              (prn updated-response)
                              updated-response))}}})

Which is circumventing the built in response mechanism. I'd still like to know the right way.