React app can't create mutations due to CORS errors

I’m using dgraph-js-http in React to create Dgraph queries and mutations. My setup is basic and I’m following tutorials to create basic to-do lists.

The tutorials I followed are here:

In all three cases, Dgraph is running in Docker on localhost:8080 and React is running on localhost:3000. In all three cases I couldn’t create mutations through the React app because I got these errors in the Chrome developer tools:

Access to fetch at ‘http://localhost:8080/graphql’ 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. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

I think I’m missing something basic about Docker or networking. I researched CORS errors and it looks like the required header must be sent from the server, but as far as I can tell, I don’t have the ability to add those headers to the responses coming from the Dgraph side.

Can anyone see the problem with my setup?

edit: The interesting thing is that this tutorial https://dgraph.io/blog/post/building-todo-list-react-dgraph/ sets up Dgraph with docker-compose, and it does let me do mutations, but not modify the schema with curl -X POST localhost:8080/admin/schema --data-binary '@schema.graphql'.

When the standalone docker version of Dgraph is used with the app from that tutorial, instead of the docker-compose version, I can modify the schema, but the above CORS errors come up.

But with this tutorial (the one with auth https://dgraph.io/docs/graphql/todo-app-tutorial/todo-overview/), CORS errors ensue regardless of whether docker-compose or the standalone Docker command is used.

As a local dev workaround, can you try if this chrome plugin allow CORS fixes your problem?

In production of course you would have everything nicely gated by your domains.

EDIT: usage of the Allow CORS extension is to be considered bad advice in general. It’s a hacky solution, that does not actually solve the problems.

2 Likes

@catherineluse that’s really odd. We do support this.

Could you paste the output of the following command:

curl -vX OPTIONS http://localhost:8080/graphql

You should see something like the following:

< HTTP/1.1 200 OK
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: X-Dgraph-AccessToken, Content-Type, Content-Length, Accept-Encoding, Cache-Control, X-CSRF-Token, X-Auth-Token, X-Requested-With
< Access-Control-Allow-Methods: POST, OPTIONS
< Access-Control-Allow-Origin: *

gja yes, I see the same thing:

HTTP/1.1 200 OK

< Access-Control-Allow-Credentials: true

< Access-Control-Allow-Headers: X-Dgraph-AccessToken, Content-Type, Content-Length, Accept-Encoding, Cache-Control, X-CSRF-Token, X-Auth-Token, X-Requested-With

< Access-Control-Allow-Methods: POST, OPTIONS

< Access-Control-Allow-Origin: *

< Connection: close

< Content-Type: application/json

< Date: Sat, 29 Aug 2020 00:50:20 GMT

< Content-Length: 0

< 

* Closing connection 0

chewxy The Chrome plugin didn’t work for me. I tried enabling CORS, then testing the requests with the plugin as shown in the screenshots below. But the requests were still blocked.

Screen Shot 2020-08-28 at 5.55.06 PM Screen Shot 2020-08-28 at 5.54.54 PM

You can simply, not use docker for this case. As you are exploring it I think it is better to run locally. Run these steps:

1 - Put down any Dgraph instance running on Docker.

2 - install Dgraph

curl https://get.dgraph.io -sSf | bash

3 - Set your default path

mkdir ~/tmp

4 - start Dgraph

# run this on your terminal
cd ~/tmp && dgraph zero & dgraph alpha

This will start both zero and alpha at the same time.
If you have issues to shutdown, you can use htop to kill it.

sudo htop
> press F4
search for "dgraph"
> select and press F9
> kill it

Now you can just start the app, and just works.

But remember to upgrade some libs, as some of the repos you’ve shared are old, you should upgrade for example dgraph-js-http.

This issue with CORS can be solved by dockerizing the whole thing. But that is a long process that you won’t take now. I guess.

@MichelDiz I don’t think that removing docker would mitigate this impact. CORS is between your browser and dgraph, so docker or not has no impact.

@catherineluse, could you share the snippet you are using to connect to the db, specifically, which HTTP library? You mentioned react, so I assume you are probably using fetch or axios or something similar?

Do note that the Request to fetch the data must be over POST for CORS to kick in (as you can see in the Access-Control-Allow-Methods). I believe we do support GET as well, but it looks like GET requests don’t work with CORS.

Here is an example that should work (run this in the browser console)

(async () => {
  const res = await fetch("http://localhost:8080/graphql", { 
    headers: {"Content-Type": "application/graphql"}, 
    method: "POST", 
    body: `{
      __schema {
        types {
          name
        }
      }
    }`
  })
  console.log(await res.json())
})()

You should see some types and such logged. If this doesn’t work, could you let us know what happened in both the console tab, as well as the network tab (you should see two network requests: an OPTIONS request, followed by a POST request)

I’m pretty sure about what I’m saying. CORS is about the origin of the assets. If you are running Dgraph on Docker and the React locally. Even if you are using “localhost” - It is a “cross-origin” unless you are using some reverse proxy. If you run all locally (or all in docker), it works just fine.

BTW, this is a misunderstanding. The Docker compose at https://dgraph.io/blog/post/building-todo-list-react-dgraph/ is using the version v1.0.13. Which doesn’t have GraphQL. Unless you have upgraded the tag on the YAML.

I’m not sure why you are running a GraphQL schema, as your examples are all about DQL. This endpoint http://localhost:8080/admin/schema is exclusive for GraphQL. If you are using DQL, your schema should go to http://llocalhost:8080/alter. See https://dgraph.io/docs/clients/raw-http/#alter-the-database

Cheers.

For the todo app without auth, it worked after I upgraded dgraph-js-http to version 20.07.0.

For the todo app with auth, the CORS errors stopped when I used the docker-compose up in which the “latest” Dgraph image was used.

Hey, do you still need help?

No, it works now. I really appreciate the help.

I proposed a couple of changes to fix the tutorials.

2 Likes

OK, let’s get these merged ASAP. Thank you!