1

I am currently working on a web app with Go/Postgres backend and React frontend. I am running into some trouble with CORS despite trying many solutions found here and around the internet.

Currently, I am using the package github.com/rs/cors to handle CORS on the server side and, checking with a curl request like

curl -D - -H 'Origin: http://localhost:3000' \
-H 'Authorization: Bearer mytoken' \
http://localhost:8000/api/companies

I get the correct response:

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:3000
Content-Type: application/json
Vary: Origin
Date: Mon, 26 Aug 2019 18:19:32 GMT
Content-Length: 273

{"data":[{"ID":1,"CreatedAt":"2019-08-23T17:54:23.43867+01:00","UpdatedAt":"2019-08-23T17:59:26.898246+01:00","DeletedAt":null,"name":"Goldman Sachs","url":"https://goldmansachs.com","industry":"Investment Banking","hq":"New York, US"}],"message":"success","success":true}

But the request fails when it is done by the React frontend with an Access to XMLHttpRequest at 'http://localhost:8000/api/companies' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. message.

main.go

func main() {
    router := mux.NewRouter()

    db := models.GetDB()
    defer db.Close()

    port := os.Getenv("PORT")
    if port == "" {
        port = "8000" //localhost
    }


    router.HandleFunc("/api/companies", handlers.GetAllCompanies).Methods("GET")
    ...


    c := cors.New(cors.Options{
        AllowedOrigins: []string{"http://localhost:3000"},
        AllowedMethods: []string{"POST", "GET", "OPTIONS", "PUT", "DELETE"},
        AllowCredentials: true,
    })

    router.Use(app.JwtAuthentication)

    handler := c.Handler(router)

    err := http.ListenAndServe(":"+port, handler)
    if err != nil {
        panic(err.Error())
    }
}

endpoints.js

...
export const token = () => {
  const localToken = getLocalAccessToken()
  //getLocalAccessToken returns the token correctly
  return localToken
}
...
const headers = {
  Authorization: `Bearer ${token()}`,
  'Content-Type': 'application/json',
};

export const getCompanies = () => axios.get(`http://localhost:8000/api/companies`, { headers }, { crossDomain: true });
...

I don't really know what to do to fix this because it works with curl but not in the browser and at the moment I am clueless to why.

Aliou Amar
  • 21
  • 1
  • 2
  • Your cors implementation only handles simple CORS requests. for more advanced ones, you'll need to properly handle the preflight. – Kevin B Aug 26 '19 at 18:38
  • @KevinB I tried that solution early on, it didn't work for me for some reason (adding the 3 headers and returning 200 if the method is "OPTIONS") – Aliou Amar Aug 26 '19 at 18:44
  • 1
    The latter part is what you are missing currently. That it didn't work for you doesn't change that you need to properly respond to the OPTIONS request. All it needs is a 200 status code and the 3 headers. It's not complicated. – Kevin B Aug 26 '19 at 18:44
  • I'll retry that then thanks :) – Aliou Amar Aug 26 '19 at 18:49

0 Answers0