sift icon indicating copy to clipboard operation
sift copied to clipboard

Option to enable CORS

Open jerrygreen opened this issue 1 year ago • 7 comments

Currently I'm not able to request my little server function on Deno Deploy that I made with sift, because I'm getting an error:

Access to fetch at '<MY_DENO_DEPLOY_URL>' from origin 'http://127.0.0.1:5173' has been blocked by CORS policy: 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.

How can I setup allowed domains for CORS with sift?

I haven't found any corresponding docs.

jerrygreen avatar Aug 14 '22 21:08 jerrygreen

I have found a way to set proper headers, i.e. I solved the issue for myself. But the issue persists in a way that normally libs provide some syntactic sugar to pass allowed domains.

jerrygreen avatar Aug 19 '22 07:08 jerrygreen

How did you manage to solve it?

Karytonn avatar Aug 25 '22 15:08 Karytonn

When returning response, you can pass headers like that:

return new Response(body, { headers })

And before that you can set headers, something like that:

const allowList = [
  'https://jerrygreen.github.io',
  // whatever origins you want to allow
]

const headers = new Headers({
  'Content-Type': 'application/json; charset=utf-8',
})

const origin = request.headers.get('origin') || ''
if (allowList.includes(origin)) {
  headers.set('Access-Control-Allow-Origin', origin) // <--- this is the key row
}

Unfortunately it doesn't work for http by some reason, because either sift, or Deno, or Deno Deploy, or maybe even browsers, – some of them replace http with https for Access-Control-Allow-Origin header entry. So in order to work on localhost, you will need either:

  1. Fake ssl option. On build tools like Vite there's cli option --ssl for that, which generates self-signed cert for localhost.
  2. Or you can also just set wildcard allowance on deno like this:
    headers.set('Access-Control-Allow-Origin', '*')
    

But wildcard is not recommended for production, CORS have their reason behind that (basically, layer of security).

Btw take notice that you can't pass the whole array to the header, and have to do your check, returning only the requested origin, – in case you allow such an origin. This is another little security measure. Returning * disables this measure for any origin for such a client.

jerrygreen avatar Aug 25 '22 20:08 jerrygreen

@jerrygreen I don't even know how to thank you, thank you so much! Thanks for your time spent! 🙏🏼

Karytonn avatar Aug 25 '22 21:08 Karytonn

@jerrygreen Unfortunately, even releasing access to all origins, I get a CORS error

That's what I tried:

const headers = new Headers({
  'Content-Type': 'application/json; charset=utf-8',
  'Access-Control-Allow-Origin': '*'
})


"/simulation": async (req: Request) => {

    if(req.method == "POST"){

        const body = await req.text(); //return body
      
        // Get and send simulation to Telegram bot
        const dataForSimulation: SimulationFormat = JSON.parse(body);
        const simulationResult = await simulator(dataForSimulation).then((result: SimulationFormat) => {
          return result;
        }).catch((err: any) => {
          console.log(err);
        });

        return new Response(JSON.stringify(simulationResult), {
          headers
        });

    } 
    return new Response("Hello", { headers });
  },

This is the error I get:

Access to XMLHttpRequest at 'https://karytonn-xxx.deno.dev/simulation' from origin 'https://www.xxx.com.br' 
has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers 
in preflight response.

Karytonn avatar Aug 25 '22 22:08 Karytonn

If you're using Github to deploy to Deno Deploy, it well might be that you pushed a commit with some syntax mistake or some non-existing variable or something. Therefore your deploy will be failed, and the older (working) code will be executed, while you're mistakenly convinced it is the new code is being executed. Make sure you have this tick in your Github repo:

image

Also, make sure that you're accessing your main (production) deployment, not some old one:

image

Normally urls like https://karytonn-XXX.deno.dev are static and never change. That is fine if you want to stick to a certain version, but maybe you want to always access to the latest api, most likely it is just https://karytonn.deno.dev, without any hashes. May depend on your configuration though.

My overall recommendations would be:

  1. When making requests from https://www.xxx.com.br, check out the response headers in developer tools, when you receive from https://karytonn-xxx.deno.dev/simulation (obviously you're not receiving Access-Control-Allow-Origin, but you should, look up into those and the other headers and see what happens there).
  2. Try setting any other header, some custom header like x-whatever, etc., to see how it works. As I said, maybe your build just failed, or you're accessing old version, therefore none of the headers aren't setting at all.
  3. Before returning response, log your request.headers.get('origin'). See in deno logs in https://dash.deno.com/projects/YOUR_PROJECT_NAME/logs

jerrygreen avatar Aug 25 '22 23:08 jerrygreen

@jerrygreen thanks for the light!

This was missing:

  headers.set('Access-Control-Allow-Origin', '*');
+ headers.set('Access-Control-Allow-Headers', '*');
+ headers.set('Access-Control-Allow-Methods', 'GET,POST');
```

Karytonn avatar Aug 26 '22 01:08 Karytonn