CORS for multiple domains

Hi.

I have developed a webclient/server application relatively easily with XData. Thanks for that.

The service needs to be accessed from different domains. So I have learned about CORS.

I have learned that CORS allows to define access for all domains (using the wildcard, which is the default for the cors middelware) or to one specific domain. This is what the cors middelware implements.

I have also learned that in case the service should grant access to multiple domain in a more secure way that accepting all, the response should be dynamic.
So I thought I would find an event in the cors middelware that would allow me to test the domain and tell with a boolean if it is allowed or not.

But there isn't such an event.

I can write my own custom middelware of course, but wouldn't it be better to have such an event in the cors middelware itself?

Or instead of an event, we could also think about a white list of domains instead of a single one. That combined with which methods would be allowed for each domain.

Hi Didier,

That's a good suggestion, indeed. And it's true that you can relatively easily implement that in your own custom middleware, indeed. So it's not a blocking issue.

Given this context, if you allow me, I will move this topic to Sparkle feature requests so we can track and eventually implement this.

Sure.

Hi Wagner,
Considering the question of Stickens Didier, about CORS for multiple domains: do you have a timeline about when this will be implemented? Or is their already another trick to use CORS for mulitple domains? My XDataServer API’s are used from different domains. Due to security reasons, i do not want to use the “Access-Control-Allow-Origin: *“ headers. So, i need a “dynamic” solution Instead. It would be ideal if the CORS middleware in XDataServer would read the origin from the senders headers and creates the appropiate CORS header for the response header if (and only if) the origin is in a list of whitelisted domains. (If its not, the request will be blocked, which is good.)
Thx, keep up the good work, i enjoy all the TMS components.

Hi @Gertjan_Westerlaken,

It's relatively easy to implement that with anonymous, generic middleware. You can just return a CORS response header yourself with the domain you want:

Just check the Origin of the request and set the Access-Control-Allow-Origin in the response.

Hi Wagner,
That makes sense too. I will use the Generic middleware and skip the CORS middleware for now. Thx!

Hi Wagner,
Thx. for the quick reply. Just a quick check to see if i’m on the right track. Using the Generic middleware to dynamicly create a CORS header from a allowed whitelist would be (more or less) something like:

procedure TServerContainer.XDataServerGenericRequest(Sender: TObject; Context: THttpServerContext; Next: THttpServerProc);
begin
  ApplyCors(Context);
  Next(Context);
end;

procedure TServerContainer.ApplyCors(Context: THttpServerContext);
var
  Origin: string;
begin
  Origin := Context.Request.Headers.Get('Origin');

  //FAllowdOrigens is a TStringList var. with whitlesited domains for the API

  if FAllowdOrigens.Contains(Origin) then  
  begin
    Context.Response.Headers.SetValue('Access-Control-Allow-Origin', Origin);
    Context.Response.Headers.SetValue('Access-Control-Allow-Credentials', 'true');
    Context.Response.Headers.SetValue('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    Context.Response.Headers.SetValue('Access-Control-Max-Age', '86400');
    Context.Response.Headers.SetValue('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
    Context.Response.Headers.SetValue('Vary', 'Origin');
  end;
end;

That's pretty much it, yes. Did it work for you?

Works like a charm! Thx