-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
features: append cors plugin #1327
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
9ba9c88
feat: add cors plugin
ShiningRush d369b9c
fix: remove unnecessary code
ShiningRush f6aa92f
fix: lint error and admin api unit test
ShiningRush 3450b65
fix: lint error when line lengeth exceeding 100
ShiningRush 3fa7118
fix: lint error
ShiningRush 0f1051a
fix: change cors priority and debug unit test
ShiningRush 3da4737
fix: optimze description
ShiningRush 2f3327b
resolve conflict
ShiningRush eba991f
refator: fix reviews
ShiningRush 954bb1c
feat: append docs
ShiningRush 8bbc29d
doc: append link to main document
ShiningRush 054988b
doc: add ref to features
ShiningRush 79e4421
doc: optimize document's format.
ShiningRush b7fcb39
doc: fix chinese comma in license header
ShiningRush File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,6 +144,6 @@ plugins: # plugin list | |
- tcp-logger | ||
- proxy-mirror | ||
- kafka-logger | ||
|
||
- cors | ||
stream_plugins: | ||
- mqtt-proxy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<!-- | ||
# | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. | ||
# The ASF licenses this file to You under the Apache License, Version 2.0 | ||
# (the "License"); you may not use this file except in compliance with | ||
# the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
--> | ||
|
||
# [English](cors.md) | ||
|
||
# 目录 | ||
|
||
- [**简介**](#简介) | ||
- [**属性**](#属性) | ||
- [**如何启用**](#如何启用) | ||
- [**测试插件**](#测试插件) | ||
- [**禁用插件**](#禁用插件) | ||
|
||
## 简介 | ||
|
||
`cors` 插件可以让你轻易地为服务端启用 [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) 的返回头。 | ||
|
||
## 属性 | ||
|
||
- `allow_origins`: `可选`,允许跨域访问的 Origin,格式如:`scheme`://`host`:`port`,比如: https://somehost.com:8081。多个值使用 `,` 分割,`allow_credential` 为 `false` 时可以使用 `*` 来表示所有 Origin 均允许通过。你也可以在启用了 `allow_credential` 后使用 `**` 强制允许所有 Origin 都通过,但请注意这样存在安全隐患。默认值为 `*`。 | ||
- `allow_methods`: `可选`,允许跨域访问的 Method,比如: `GET`,`POST`等。多个值使用 `,` 分割,`allow_credential` 为 `false` 时可以使用 `*` 来表示所有 Origin 均允许通过。你也可以在启用了 `allow_credential` 后使用 `**` 强制允许所有 Method 都通过,但请注意这样存在安全隐患。默认值为 `*`。 | ||
- `allow_headers`: `可选`,允许跨域访问时请求方携带哪些非 `CORS规范` 以外的 Header, 多个值使用 `,` 分割。默认值为 `*`。 | ||
- `expose_headers`: `可选`,允许跨域访问时响应方携带哪些非 `CORS规范` 以外的 Header, 多个值使用 `,` 分割。默认值为 `*`。 | ||
- `max_age`: `可选`,浏览器缓存 CORS 结果的最大时间,单位为秒,在这个时间范围内浏览器会复用上一次的检查结果,`-1` 表示不缓存。请注意各个浏览器允许的的最大时间不用,详情请参考 [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#Directives). 默认值为 `5`。 | ||
- `allow_credential`: 是否允许跨域访问的请求方携带凭据(如 Cookie 等),默认值为: `false`。 | ||
|
||
## 如何启用 | ||
|
||
创建 `Route` 或 `Service` 对象,并配置 `cors` 插件。 | ||
|
||
```shell | ||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' | ||
{ | ||
"uri": "/hello", | ||
"plugins": { | ||
"cors": {} | ||
}, | ||
"upstream": { | ||
"type": "roundrobin", | ||
"nodes": { | ||
"127.0.0.1:8080": 1 | ||
} | ||
} | ||
}' | ||
``` | ||
|
||
## 测试插件 | ||
|
||
请求下接口,发现接口已经返回了`CORS`相关的header,代表插件生效 | ||
```shell | ||
curl http://127.0.0.1:9080/hello -v | ||
... | ||
< Server: APISIX web server | ||
< Access-Control-Allow-Origin: * | ||
< Access-Control-Allow-Methods: * | ||
< Access-Control-Allow-Headers: * | ||
< Access-Control-Expose-Headers: * | ||
< Access-Control-Max-Age: 5 | ||
... | ||
``` | ||
|
||
## 禁用插件 | ||
|
||
从配置中移除`cors`插件即可。 | ||
```shell | ||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' | ||
{ | ||
"uri": "/hello", | ||
"plugins": {}, | ||
"upstream": { | ||
"type": "roundrobin", | ||
"nodes": { | ||
"127.0.0.1:8080": 1 | ||
} | ||
} | ||
}' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<!-- | ||
# | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. | ||
# The ASF licenses this file to You under the Apache License, Version 2.0 | ||
# (the "License"); you may not use this file except in compliance with | ||
# the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
--> | ||
|
||
# [Chinese](cors-cn.md) | ||
|
||
# Summary | ||
|
||
- [**Description**](#Description) | ||
- [**Attributes**](#Attributes) | ||
- [**How To Enable**](#how-to-Enable) | ||
- [**Test Plugin**](#test-plugin) | ||
- [**Disable Plugin**](#disable-plugin) | ||
|
||
## Description | ||
|
||
`cors` plugin can help you enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) easily. | ||
|
||
## Attributes | ||
|
||
- `allow_origins`: `optional`, Which Origins is allowed to enable CORS, format as:`scheme`://`host`:`port`, for example: https://somehost.com:8081. Multiple origin use `,` to split. When `allow_credential` is `false`, you can use `*` to indicate allow all any origin. you alse can allow all any origins forcefully using `**` even already enable `allow_credential`, but it will bring some securiy risks. Default value: `*`. | ||
- `allow_methods`: `optional`, Which Method is allowed to enable CORS, such as: `GET`, `POST` etc. Multiple method use `,` to split. When `allow_credential` is `false`, you can use `*` to indicate allow all any method. You alse can allow all any method forcefully using `**` even already enable `allow_credential`, but it will bring some securiy risks. Default value: `*`. | ||
- `allow_headers`: `optional`, Which headers are allowed to set in requst when access cross-origin resource. Multiple value use `,` to split. Default value: `*`. | ||
- `expose_headers`: `optional`, Which headers are allowed to set in response when access cross-origin resource. Multiple value use `,` to split. Default value: `*`. | ||
- `max_age`: `optional`, Maximum number of seconds the results can be cached.. Within this time range, the browser will reuse the last check result. `-1` means no cache. Please note that the maximum value is depended on browser, please refer to [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#Directives) for details.Default value: `5`. | ||
- `allow_credential`: Enable request include credentia (such as Cookie etc.), Default avlue: `false`. | ||
|
||
## How To Enable | ||
|
||
Create a `Route` or `Service` object and configure `cors` plugin. | ||
|
||
```shell | ||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' | ||
{ | ||
"uri": "/hello", | ||
"plugins": { | ||
"cors": {} | ||
}, | ||
"upstream": { | ||
"type": "roundrobin", | ||
"nodes": { | ||
"127.0.0.1:8080": 1 | ||
} | ||
} | ||
}' | ||
``` | ||
|
||
## Test Plugin | ||
|
||
curl to server, you will find the headers about `CORS` is be returned, it means plugin is working fine. | ||
|
||
```shell | ||
curl http://127.0.0.1:9080/hello -v | ||
... | ||
< Server: APISIX web server | ||
< Access-Control-Allow-Origin: * | ||
< Access-Control-Allow-Methods: * | ||
< Access-Control-Allow-Headers: * | ||
< Access-Control-Expose-Headers: * | ||
< Access-Control-Max-Age: 5 | ||
... | ||
``` | ||
|
||
## Disable Plugin | ||
|
||
Remove plugin from configuraion. | ||
|
||
```shell | ||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' | ||
{ | ||
"uri": "/hello", | ||
"plugins": {}, | ||
"upstream": { | ||
"type": "roundrobin", | ||
"nodes": { | ||
"127.0.0.1:8080": 1 | ||
} | ||
} | ||
}' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
-- | ||
-- Licensed to the Apache Software Foundation (ASF) under one or more | ||
-- contributor license agreements. See the NOTICE file distributed with | ||
-- this work for additional information regarding copyright ownership. | ||
-- The ASF licenses this file to You under the Apache License, Version 2.0 | ||
-- (the "License"); you may not use this file except in compliance with | ||
-- the License. You may obtain a copy of the License at | ||
-- | ||
-- http://www.apache.org/licenses/LICENSE-2.0 | ||
-- | ||
-- Unless required by applicable law or agreed to in writing, software | ||
-- distributed under the License is distributed on an "AS IS" BASIS, | ||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
-- See the License for the specific language governing permissions and | ||
-- limitations under the License. | ||
-- | ||
local core = require("apisix.core") | ||
local ngx = ngx | ||
local plugin_name = "cors" | ||
local str_find = string.find | ||
local re_gmatch = ngx.re.gmatch | ||
|
||
local schema = { | ||
type = "object", | ||
properties = { | ||
allow_origins = { | ||
description = | ||
"you can use '*' to allow all origins when no credentials," .. | ||
"'**' to allow forcefully(it will bring some security risks, be carefully)," .. | ||
"multiple origin use ',' to split. default: *.", | ||
type = "string", | ||
default = "*" | ||
}, | ||
allow_methods = { | ||
description = | ||
"you can use '*' to allow all methods when no credentials and '**'," .. | ||
"'**' to allow forcefully(it will bring some security risks, be carefully)," .. | ||
"multiple method use ',' to split. default: *.", | ||
type = "string", | ||
default = "*" | ||
}, | ||
allow_headers = { | ||
description = | ||
"you can use '*' to allow all header when no credentials," .. | ||
"multiple header use ',' to split. default: *.", | ||
type = "string", | ||
default = "*" | ||
}, | ||
expose_headers = { | ||
description = | ||
"you can use '*' to expose all header when no credentials," .. | ||
"multiple header use ',' to split. default: *.", | ||
type = "string", | ||
default = "*" | ||
}, | ||
max_age = { | ||
description = | ||
"maximum number of seconds the results can be cached." .. | ||
"-1 mean no cached,the max value is depend on browser," .. | ||
"more detail plz check MDN. default: 5.", | ||
type = "integer", | ||
default = 5 | ||
}, | ||
allow_credential = { | ||
type = "boolean", | ||
default = false | ||
}, | ||
} | ||
} | ||
|
||
local _M = { | ||
version = 0.1, | ||
priority = 4000, | ||
type = 'auth', | ||
name = plugin_name, | ||
schema = schema, | ||
} | ||
|
||
function _M.check_schema(conf) | ||
local ok, err = core.schema.check(schema, conf) | ||
if not ok then | ||
return false, err | ||
end | ||
|
||
return true | ||
end | ||
|
||
function _M.header_filter(conf, ctx) | ||
if conf.allow_origins == "**" then | ||
conf.allow_origins = ngx.var.http_origin or '*' | ||
end | ||
if str_find(conf.allow_origins, ",", 1, true) then | ||
local finded = false | ||
local iterator, err = re_gmatch(conf.allow_origins, "([^,]+)", "jiox") | ||
if not iterator then | ||
return 500, {message = "match origins failed", error = err} | ||
end | ||
while true do | ||
local origin, err = iterator() | ||
if err then | ||
return 500, {message = "iterate origins failed", error = err} | ||
end | ||
if not origin then | ||
break | ||
end | ||
|
||
if origin[0] == ngx.var.http_origin then | ||
conf.allow_origins = origin[0] | ||
finded = true | ||
break | ||
end | ||
end | ||
if not finded then | ||
return | ||
end | ||
end | ||
|
||
if conf.allow_methods == "**" then | ||
conf.allow_methods = "GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,CONNECT,TRACE" | ||
end | ||
|
||
ngx.header["Access-Control-Allow-Origin"] = conf.allow_origins | ||
ngx.header["Access-Control-Allow-Methods"] = conf.allow_methods | ||
ngx.header["Access-Control-Allow-Headers"] = conf.allow_headers | ||
ngx.header["Access-Control-Expose-Headers"] = conf.expose_headers | ||
ngx.header["Access-Control-Max-Age"] = conf.max_age | ||
if conf.allow_credential then | ||
ngx.header["Access-Control-Allow-Credentials"] = true | ||
end | ||
|
||
if ctx.var.request_method == "OPTIONS" then | ||
return 200 | ||
end | ||
end | ||
|
||
return _M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
add a blank line