NethermindEth / juno

Starknet client implementation.
https://juno.nethermind.io
Apache License 2.0
387 stars 167 forks source link

CORS error when using Juno RPC in Argent X #1694

Closed chichi13 closed 7 months ago

chichi13 commented 7 months ago

We have a web application who needs to connect Starknet through Argent X (or another one). I've put our RPC in Argent X configuration. I get CORS errors when I put our Sepolia RPC into Argent X.

Here is the Juno configuration:

ExecStart=/home/starknet/bin/juno --db-path /home/starknet/starknet-sepolia-data --network sepolia \
--http \
--http-port 6060 \
--ws \
--ws-port 9545 \
--eth-node="wss://my-eth-node" \
--metrics true \
--metrics-host 0.0.0.0 \
--metrics-port 9090

When I don't put any header in my nginx configuration, I get the following error:

Access to fetch at 'https://rpc-sepolia-starknet-02.nodeguardians.io/' from origin 'https://nodeguardians.io' 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.

Here is the network tab of the "inspect" page (F12):

image

The nginx configuration is very basic with a proxy_pass to Juno:

server {
    listen 80;
    server_name rpc-sepolia-starknet-02.nodeguardians.io;

    location / {
        proxy_redirect                      off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout          10m;
        proxy_connect_timeout       1m;
        proxy_pass      http://127.0.0.1:6060;
    }

    location /websocket {
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://127.0.0.1:9545/websocket;
    }
}

However, as soon as I add headers like we do for other RPCs I get a strange error again, as if Juno was responding with a '*' header by default (which it looks like it is by looking at the code here):

Access to fetch at 'https://rpc-sepolia-starknet-02.nodeguardians.io/' from origin 'https://nodeguardians.io' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Here is the network tab of the "inspect" page (F12):

image

And the nginx configuration, with the basic headers:

server {
    listen 80;
    server_name rpc-sepolia-starknet-02.nodeguardians.io;

    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Methods' '*' always;
    add_header 'Access-Control-Allow-Headers' '*' always;

    location / {
        proxy_redirect                      off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout          10m;
        proxy_connect_timeout       1m;
        proxy_pass      http://127.0.0.1:6060;
    }

    location /websocket {
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://127.0.0.1:9545/websocket;
    }
}

The most important thing in this log is: The 'Access-Control-Allow-Origin' header contains multiple values '*, *'. I don't really know exactly why we have this error whereas here we only add the 'Access-Control-Allow-Origin' once, with a value of '*'.

Can you confirm that Juno returns Access-Control-Allow-Origin: '*' by default? Also, how can I get Juno to work in my case? (Web application that connects to Argent X, linked to our Sepolia RPC)

Would it be possible to add a flag --http.cors (or something like that) to give the user the choice of enabling CORS or not? (disabled by default if possible, so we can manage CORS with nginx). Also, it will let the choice of origin authorised, and not only '*'

omerfirmak commented 7 months ago

Hey @chichi13,

Can you confirm that Juno returns Access-Control-Allow-Origin: '*' by default?

Yeap, that is the default behavior for Juno.

Would it be possible to add a flag --http.cors (or something like that) to give the user the choice of enabling CORS or not? (disabled by default if possible, so we can manage CORS with nginx). Also, it will let the choice of origin authorised, and not only '*'

That is an option as well

Also, how can I get Juno to work in my case? (Web application that connects to Argent X, linked to our Sepolia RPC)

Let me forward this to our DevOps team to see if they can help you.

gehlotanish commented 7 months ago

Hey @chichi13,

can you try the below nginx configuration?

server {
    listen 80;
    server_name rpc-sepolia-starknet-02.nodeguardians.io;
    location / {
        proxy_redirect                      off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout          10m;
        proxy_connect_timeout       1m;
        proxy_pass      http://127.0.0.1:6060;
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' '*' always;
        add_header 'Access-Control-Allow-Headers' '*' always;
    }
    location /websocket {
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://127.0.0.1:9545/websocket;
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' '*' always;
        add_header 'Access-Control-Allow-Headers' '*' always;
    }
}
chichi13 commented 7 months ago

Unfortunately the problem is the same:

Access to fetch at 'https://starknet-goerli-02.nodeguardians.io/' from origin 'https://nodeguardians.io' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Looks like the default '*' from Juno is the problem here :/ What I don't understand is: why it's not working without add_header 'Access-Control-Allow-Origin' '*' always; since Juno already returns '*'

omerfirmak commented 7 months ago

We will just add ability to disable cors :+1:

chichi13 commented 7 months ago

Perfect!

omerfirmak commented 7 months ago

Done in #1696, should be in the next release

mrostamii commented 1 week ago

After that PR, it's possible to add the following tag, and it will add the CORS headers to RPC responses:

--rpc-cors-enable