r0man / cljs-http

A ClojureScript HTTP library.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Struggling with CORS post request to compojure / ring backend using ring.core / cljs-http...

opened this issue · comments

Hey all, firstly, thanks for the project! @r0man have also been working with ring-cors to try to get this sorted. I have, however gotten hung up on some preflight issues on the cljs-https side.

Server code (uses compojure / ring / misc middleware):
https://github.com/ckuttruff/orghub-clj/blob/master/src/orghub/server.clj

Relevant section (sorry, started to throw the kitchen sink at these headers):

(def app (-> app-routes
             (wrap-cors  :access-control-allow-origin [#"^(http(s)?://)?localhost:(\d){4}$"]
                         :access-control-allow-credentials true
                         :access-control-allow-methods [:get :post :options]
                         :access-control-allow-headers ["Content-Type" "Accept" "Cache-Control" "Origin" "User-Agent"])))

The following curl command works swimmingly:

$ curl -i  -d '{"email":"foo@gmail.com", "password":"foo"}' -H "Content-Type: application/json"  -X POST localhost:3000/loginHTTP/1.1 200 OK
Date: Sat, 19 May 2018 19:32:21 GMT
Content-Length: 0
Server: Jetty(9.2.21.v20170120)

But the following cljs-http call fails with XHR failed loading: OPTIONS:
https://github.com/ckuttruff/orghub-clj/blob/master/src/orghub/components/login.cljs

  (go (let [response (<! (http/post "http://localhost:3000/login"
                                    {:json-params {:email email :password pw}
       
                                     }))]
        (prn response)
        (prn (:status response))
        (prn (map :login (:body response)))))

Thanks in advance for any insights you might be able to provide. I'm sorry if I've missed something obvious, but I've been digging into CORS docs and am just having difficulty cause I'm not even spawning the preflight request and I'm not sure why the behavior would be different for the curl command (is that not triggering the same CORS request?)

Cheers! Thanks again for your work on this and other cljs projects!

ooohhh, the plot thickens... got more useful debug output from firefox than chrome:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3000/login. (Reason: expected ‘true’ in CORS header ‘Access-Control-Allow-Credentials’).

gonna try setting that now

lol, okay, so this change addressed one issue. #FunWithTyping
https://github.com/ckuttruff/orghub-clj/commit/6c3a51250a072f14b0d2a35827ccd5021848ea86

I was passing a boolean into the header whereas a string was expected for Access-Control-Allow-Credentials

-                         :access-control-allow-credentials true
+                         :access-control-allow-credentials "true"

Incredibly this fixes things for firefox, but not for chrome. So there's a secondary issue with headers here in terms of what chrome is sending and what the server is expecting

headers

A side-by-side of the request headers.
Chrome (on the left) gets XHR failed loading: POST "http://localhost:3000/login".
Firefox (on the right) succeeds.

Obv some minor differences here. Gonna dig into the CORS docs to see what's up here...

For the visually impaired (and the search engines), here's the text of the headers.
chrome:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: localhost:3449
If-None-Match: 4017874760
Referer: http://localhost:3449/
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36

firefox:

Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.5
Connection: keep-alive
Content-Length: 48
Content-Type: application/json
Host: localhost:3000
Origin: http://localhost:3449
Referer: http://localhost:3449/
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linu…) Gecko/20100101 Firefox/60.0

p.s. to folks running lein figwheel alongside lein ring server:

The simplest thing for me was to set a handler on the clj side and unify the traffic under the same port (such that it won't trigger CORS (which has been a gigantic pain to try to figure out)).

Here's the commit that got things working for me:
https://github.com/ckuttruff/orghub-clj/commit/190d4129057f93484104df97255e252e722dba9f

And there's a dead simple example of using the ring-handler option in figwheel here:
https://github.com/bhauman/lein-figwheel/tree/master/examples/using-ring-handler

No more futzing around between localhost:3000 and localhost:3449
More secure anyways and more like how production will be running.

I know this doesn't resolve the underlying XHR failure here, and best of luck to folks still in that fight, but this is a perfectly reasonable resolution for me :) I will close, but if others still find a need to sort this out and resurrect, please do.

Thanks all.

Hi @ckuttruff, I'm facing the same issue. Did you get around it? I can see you switched your project over to Ruby - not a good sign, but thought I should ask anyway.

@divs1210 sorry moved repo:
https://github.com/ckuttruff/orghub-clj/commit/190d4129057f93484104df97255e252e722dba9f

The code in there should show my approach. I believe I got this sorted but was dealing with other issues such that I wanted to simplify.

Would love to use clj / cljs, but yeah, started with ruby one and stripped out all the progressive web app stuff and a lot of the front-end complexity and offline ambitions.

I def got over this CORS hurdle so lemme know if that commit of later code is unclear. Gist is to run on same server to avoid CORS altogether. Lol this is bringing back bad memories. All this was a headache

@divs1210 I updated stale links. Hope it's helpful. Good luck!

@ckuttruff Glad to know you got it to work. Thank you so much!