-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Allow multiple origin domains for CORS #1973
Allow multiple origin domains for CORS #1973
Conversation
This commit references @danielvijge’s commit eurail@cc7be41 and has been rebased on top of next
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx for your contribution. Some comments...
local function configure_origin(ngx, conf) | ||
if conf.origin == nil then | ||
local origin = ngx.req.get_headers()["origin"] or nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The or nil
does not make sense here, can be removed
@@ -7,6 +7,7 @@ return { | |||
methods = { type = "array", enum = { "HEAD", "GET", "POST", "PUT", "PATCH", "DELETE" } }, | |||
max_age = { type = "number" }, | |||
credentials = { type = "boolean", default = false }, | |||
preflight_continue = { type = "boolean", default = false } | |||
preflight_continue = { type = "boolean", default = false }, | |||
origin_domains = { type = "array" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this array requires validation of its contents (and accompanying tests)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
additionally, not knowing CORS in-depth, shouldn't origin
and origin-domains
be mutually exclusive?
…l-allow-origin-response-header) there should be a way to define a list of origins on the Origin request header, but with a note stating "In practice the origin-list-or-null production is more constrained. Rather than allowing a space-separated list of origins, it is either a single origin or the string "null"."
I have added some comments on the original #1774 |
@@ -181,5 +199,27 @@ describe("Plugin: cors (access)", function() | |||
assert.is_nil(res.headers["Access-Control-Allow-Credentials"]) | |||
assert.is_nil(res.headers["Access-Control-Max-Age"]) | |||
end) | |||
it("sets CORS orgin based on origin host", function() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: "orgin"
local function configure_origin(ngx, conf) | ||
local origin = ngx.req.get_headers()["origin"] or nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's only do this in the else
branch a couple lines underneath. Also, no need for or nil
.
if conf.origin == nil then | ||
ngx.header["Access-Control-Allow-Origin"] = "*" | ||
else | ||
ngx.header["Access-Control-Allow-Origin"] = conf.origin | ||
ngx.header["Vary"] = "Origin" | ||
if origin ~= nil and host_in_domain(origin, conf) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if origin
, no need for ~= nil
@@ -7,12 +7,24 @@ CorsHandler.PRIORITY = 2000 | |||
|
|||
local OPTIONS = "OPTIONS" | |||
|
|||
local function host_in_domain(domain, conf) | |||
for i, d in ipairs(conf.origin) do | |||
if string.match(domain, '[%.|//]'..d..'$') then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do a couple things here:
- use the PCRE API offered by
ngx.re
: https://github.com/openresty/lua-nginx-module#ngxrematch - build the regex ahead of time instead of on every request
Replaced by #2203 with a new commit on top of yours which fixes the missing requirements. Thanks again! |
This PR references 1774 contributed by @danielvijge and has been rebased on top of next.
Summary
When several domains consume an API, the CORS header Access-Control-Allow-Origin is not as useful, because it only allows one domain, or all domains (with "*"). The specs do not allow for a list of domains. This change works around this by comparing the Origin header to a list of configured domain in the array 'origin_domains'. It tests if the end of the domain matches either ".{domain}" or "//{domain}". Thus, if origins_domain="example.com, example.net", a request from Origin="http://www.example.com" would be allowed, as does a request from Origin="http://example.com". But Origin="http://my-example.com" is not allowed. In this case, no Access-Control-Allow-Origin header is set.
If both origin and origin_domains are configured, origin_domains take precedence over origin.
Full changelog
Issues resolved
Fix #1043