Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CORS support #222

Open
subfuzion opened this issue May 10, 2021 · 11 comments
Open

CORS support #222

subfuzion opened this issue May 10, 2021 · 11 comments

Comments

@subfuzion
Copy link
Member

subfuzion commented May 10, 2021

If a request comes from a script running under a different origin (for our purposes here, a tuple that includes a host and port) from the origin that is hosting a function app, the request will fail due to lack of cross-origin resource sharing (CORS protocol) support.

For background, browsers restrict cross-origin HTTP requests initiated from scripts for security purposes, so if a browser runs, for example, a Flutter app loaded from a different origin than the origin hosting, for example, a Dart function app, the request will fail if the function app doesn't support CORS.

As part of supporting CORS, a function app must be able to handle the CORS preflight, which is sent as an HTTP OPTIONS request.

What would be useful for this situation is to add CORS support to the framework that would allow specifying a CORS policy, possible as metadata annotation or as an API, for setting a policy. For inspiration, see the Node.js cors package.

References:

@subfuzion
Copy link
Member Author

This is not a spec right now, but just a brainstorming comment.

Initial support could be to handle a CORS request for no support and for wildcard support.

Following that, we could extend support for specific origins. As long as we ensure the framework responds to the client with an Access-Control-Allow-Origin that returns the origin exactly as supplied by the client in the preflight request, we can design the CORS support on the framework side to enhance the basic spec with at least basic globbing support, if not full regex support, to handle at least the following case:

When the client sends an Origin request header (scheme "://" host [ ":" port ]), the port will generally be auto-selected by the browser. On the server side, the spec only supports a specific integer value, if supplied. We want to make it easy to handle requests from a particular origin on any port, with support for globbing or regexes, etc.

@Kleak
Copy link

Kleak commented May 24, 2021

I provide a cors middleware in my self_helpers but something like cors from ktor could be really great.

We can probably improve my API but for those who want something basic it can do it, just add the middleware :)

Would be happy to participate to improving this.

@djildo
Copy link

djildo commented May 29, 2021

Hello, not being able to use CORS as middleware, the expected is a List Args, any tips?

2 similar comments
@djildo
Copy link

djildo commented May 29, 2021

Hello, not being able to use CORS as middleware, the expected is a List Args, any tips?

@djildo
Copy link

djildo commented May 29, 2021

Hello, not being able to use CORS as middleware, the expected is a List Args, any tips?

@mtwichel
Copy link

mtwichel commented Jun 8, 2021

I provide a cors middleware in my self_helpers but something like cors from ktor could be really great.

We can probably improve my API but for those who want something basic it can do it, just add the middleware :)

Would be happy to participate to improving this.

I think adding middleware support could be really cool. I brought up some ideas how to do it in this comment. That way we could handle cors but also verify authentication tokens, initialize api clients, ect.

@Kleak
Copy link

Kleak commented Jun 8, 2021

I provide a cors middleware in my self_helpers but something like cors from ktor could be really great.

We can probably improve my API but for those who want something basic it can do it, just add the middleware :)

Would be happy to participate to improving this.

I think adding middleware support could be really cool. I brought up some ideas how to do it in this comment. That way we could handle cors but also verify authentication tokens, initialize api clients, ect.

In fact you don't need to change the API.
If you use Pipeline.addMiddleware will do the same no ?
Or is this more to initialize things before hand

@jpeiffer
Copy link

I created this PR: #317

With it is an example of using shelf_cors_headers now applied to the fullstack/backend.

I'm hoping the simplicity of this change will allow it to avoid the fate of #250.

@jpeiffer
Copy link

jpeiffer commented Jul 5, 2022

I think it's fair to assume my hopes have been crushed...

@mtwichel
Copy link

mtwichel commented Jul 6, 2022

Haha I really recommend checking out dart_frog if you want to do more complicated stuff with Dart on the server and want a framework to simplify the shelf stuff. It's pretty clear that at least for now, Google wants this project to be super simple and easy to use (which I understand).

@jimmyff
Copy link

jimmyff commented Oct 27, 2022

Here is my little solution/shim using the shelf_cors_headers package:

I'm using the middleware in the lib/functions.dart file like so:

// lib/functions.dart

@CloudFunction()
Future<Response> function(Request request) async {
  var handler = const Pipeline()
      .addMiddleware(corsHeaders(
          // Allow specific headers expected by my app
          headers: {'Access-Control-Allow-Headers': 'Token, Content-Type'},
          // Check origin against a list of my client domains
          originChecker: (origin) {
            return const [
              'https://mydomain.com',
              'https://example.mydomain.com',
              'https://myfirebaseapp.web.app',
              'https://myfirebaseapp.firebaseapp.com',
            ].contains(origin);
          }))
      .addHandler(corsFunction);
  return handler(request);
}

Future<Response> corsFunction(Request request) async {
  // main cloud function body...
}

The corsHeaders arguments are optional and this is just how I have it configured for my specific app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants