Skip to content

Commit

Permalink
refactor(consumer): remove id and use username only (apache#2679)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacewander authored Nov 18, 2020
1 parent e4de3d5 commit 1a24c2a
Show file tree
Hide file tree
Showing 24 changed files with 77 additions and 84 deletions.
13 changes: 4 additions & 9 deletions apisix/admin/consumers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,12 @@ local _M = {
}


local function check_conf(consumer_name, conf)
local function check_conf(conf)
-- core.log.error(core.json.encode(conf))
if not conf then
return nil, {error_msg = "missing configurations"}
end

local consumer_name = conf.username or consumer_name
if not consumer_name then
return nil, {error_msg = "missing consumer name"}
end

core.log.info("schema: ", core.json.delay_encode(core.schema.consumer))
core.log.info("conf : ", core.json.delay_encode(conf))
local ok, err = core.schema.check(core.schema.consumer, conf)
Expand Down Expand Up @@ -65,12 +60,12 @@ local function check_conf(consumer_name, conf)
end
end

return consumer_name
return conf.username
end


function _M.put(consumer_name, conf)
local consumer_name, err = check_conf(consumer_name, conf)
function _M.put(_, conf)
local consumer_name, err = check_conf(conf)
if not consumer_name then
return 400, err
end
Expand Down
2 changes: 1 addition & 1 deletion apisix/balancer/chash.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ local function fetch_chash_hash_key(ctx, upstream)
local chash_key

if hash_on == "consumer" then
chash_key = ctx.consumer_id
chash_key = ctx.consumer_name
elseif hash_on == "vars" then
chash_key = ctx.var[key]
elseif hash_on == "header" then
Expand Down
4 changes: 3 additions & 1 deletion apisix/consumer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ local function plugin_consumer()
end

local new_consumer = core.table.clone(consumer.value)
new_consumer.consumer_id = new_consumer.id
-- Note: the id here is the key of consumer data, which
-- is 'username' field in admin
new_consumer.consumer_name = new_consumer.id
new_consumer.auth_conf = config
core.log.info("consumer:", core.json.delay_encode(new_consumer))
core.table.insert(plugins[name].nodes, new_consumer)
Expand Down
4 changes: 2 additions & 2 deletions apisix/core/ctx.lua
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ do
elseif key == "service_id" then
val = ngx.ctx.api_ctx and ngx.ctx.api_ctx.service_id

elseif key == "consumer_name" or key == "consumer_id" then
val = ngx.ctx.api_ctx and ngx.ctx.api_ctx.consumer_id
elseif key == "consumer_name" then
val = ngx.ctx.api_ctx and ngx.ctx.api_ctx.consumer_name

else
val = get_var(key, t._request)
Expand Down
2 changes: 1 addition & 1 deletion apisix/plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ function _M.merge_consumer_route(route_conf, consumer_conf, api_ctx)
api_ctx.conf_type = api_ctx.conf_type .. "&consumer"
api_ctx.conf_version = api_ctx.conf_version .. "&" ..
api_ctx.consumer_ver
api_ctx.conf_id = api_ctx.conf_id .. "&" .. api_ctx.consumer_id
api_ctx.conf_id = api_ctx.conf_id .. "&" .. api_ctx.consumer_name

return new_conf, new_conf ~= route_conf
end
Expand Down
10 changes: 5 additions & 5 deletions apisix/plugins/basic-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,18 @@ end

local create_consume_cache
do
local consumer_ids = {}
local consumer_names = {}

function create_consume_cache(consumers)
core.table.clear(consumer_ids)
core.table.clear(consumer_names)

for _, cur_consumer in ipairs(consumers.nodes) do
core.log.info("consumer node: ",
core.json.delay_encode(cur_consumer))
consumer_ids[cur_consumer.auth_conf.username] = cur_consumer
consumer_names[cur_consumer.auth_conf.username] = cur_consumer
end

return consumer_ids
return consumer_names
end
end

Expand Down Expand Up @@ -164,7 +164,7 @@ function _M.access(conf, ctx)
end

ctx.consumer = cur_consumer
ctx.consumer_id = cur_consumer.consumer_id
ctx.consumer_name = cur_consumer.consumer_name
ctx.consumer_ver = consumer_conf.conf_version

core.log.info("hit basic-auth access")
Expand Down
2 changes: 1 addition & 1 deletion apisix/plugins/consumer-restriction.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ local fetch_val_funcs = {
return ctx.service_id
end,
["consumer_name"] = function(ctx)
return ctx.consumer_id
return ctx.consumer_name
end
}

Expand Down
10 changes: 5 additions & 5 deletions apisix/plugins/hmac-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,17 @@ end

local create_consumer_cache
do
local consumer_ids = {}
local consumer_names = {}

function create_consumer_cache(consumers)
core.table.clear(consumer_ids)
core.table.clear(consumer_names)

for _, consumer in ipairs(consumers.nodes) do
core.log.info("consumer node: ", core.json.delay_encode(consumer))
consumer_ids[consumer.auth_conf.access_key] = consumer
consumer_names[consumer.auth_conf.access_key] = consumer
end

return consumer_ids
return consumer_names
end

end -- do
Expand Down Expand Up @@ -404,7 +404,7 @@ function _M.rewrite(conf, ctx)

local consumer_conf = consumer.plugin(plugin_name)
ctx.consumer = validated_consumer
ctx.consumer_id = validated_consumer.consumer_id
ctx.consumer_name = validated_consumer.consumer_name
ctx.consumer_ver = consumer_conf.conf_version
core.log.info("hit hmac-auth rewrite")
end
Expand Down
10 changes: 5 additions & 5 deletions apisix/plugins/jwt-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,17 @@ local _M = {

local create_consume_cache
do
local consumer_ids = {}
local consumer_names = {}

function create_consume_cache(consumers)
core.table.clear(consumer_ids)
core.table.clear(consumer_names)

for _, consumer in ipairs(consumers.nodes) do
core.log.info("consumer node: ", core.json.delay_encode(consumer))
consumer_ids[consumer.auth_conf.key] = consumer
consumer_names[consumer.auth_conf.key] = consumer
end

return consumer_ids
return consumer_names
end

end -- do
Expand Down Expand Up @@ -265,7 +265,7 @@ function _M.rewrite(conf, ctx)
end

ctx.consumer = consumer
ctx.consumer_id = consumer.consumer_id
ctx.consumer_name = consumer.consumer_name
ctx.consumer_ver = consumer_conf.conf_version
core.log.info("hit jwt-auth rewrite")
end
Expand Down
10 changes: 5 additions & 5 deletions apisix/plugins/key-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,17 @@ local _M = {

local create_consume_cache
do
local consumer_ids = {}
local consumer_names = {}

function create_consume_cache(consumers)
core.table.clear(consumer_ids)
core.table.clear(consumer_names)

for _, consumer in ipairs(consumers.nodes) do
core.log.info("consumer node: ", core.json.delay_encode(consumer))
consumer_ids[consumer.auth_conf.key] = consumer
consumer_names[consumer.auth_conf.key] = consumer
end

return consumer_ids
return consumer_names
end

end -- do
Expand Down Expand Up @@ -98,7 +98,7 @@ function _M.rewrite(conf, ctx)
core.log.info("consumer: ", core.json.delay_encode(consumer))

ctx.consumer = consumer
ctx.consumer_id = consumer.consumer_id
ctx.consumer_name = consumer.consumer_name
ctx.consumer_ver = consumer_conf.conf_version
core.log.info("hit key-auth rewrite")
end
Expand Down
4 changes: 2 additions & 2 deletions apisix/plugins/limit-req.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ function _M.access(conf, ctx)

local key
if conf.key == "consumer_name" then
if not ctx.consumer_id then
if not ctx.consumer_name then
core.log.error("consumer not found.")
return 500, { message = "Consumer not found."}
end
key = ctx.consumer_id .. ctx.conf_type .. ctx.conf_version
key = ctx.consumer_name .. ctx.conf_type .. ctx.conf_version

else
key = (ctx.var[conf.key] or "") .. ctx.conf_type .. ctx.conf_version
Expand Down
12 changes: 6 additions & 6 deletions apisix/plugins/prometheus/exporter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ function _M.log(conf, ctx)
local route_id = ""
local balancer_ip = ctx.balancer_ip or ""
local service_id
local consumer_id = ctx.consumer_id or ""
local consumer_name = ctx.consumer_name or ""

local matched_route = ctx.matched_route and ctx.matched_route.value
if matched_route then
Expand All @@ -145,24 +145,24 @@ function _M.log(conf, ctx)

metrics.status:inc(1,
gen_arr(vars.status, route_id, matched_uri, matched_host,
service_id, consumer_id, balancer_ip))
service_id, consumer_name, balancer_ip))

local latency = (ngx.now() - ngx.req.start_time()) * 1000
metrics.latency:observe(latency,
gen_arr("request", service_id, consumer_id, balancer_ip))
gen_arr("request", service_id, consumer_name, balancer_ip))

local overhead = latency
if ctx.var.upstream_response_time then
overhead = overhead - tonumber(ctx.var.upstream_response_time) * 1000
end
metrics.overhead:observe(overhead,
gen_arr("request", service_id, consumer_id, balancer_ip))
gen_arr("request", service_id, consumer_name, balancer_ip))

metrics.bandwidth:inc(vars.request_length,
gen_arr("ingress", route_id, service_id, consumer_id, balancer_ip))
gen_arr("ingress", route_id, service_id, consumer_name, balancer_ip))

metrics.bandwidth:inc(vars.bytes_sent,
gen_arr("egress", route_id, service_id, consumer_id, balancer_ip))
gen_arr("egress", route_id, service_id, consumer_name, balancer_ip))
end


Expand Down
8 changes: 4 additions & 4 deletions apisix/plugins/wolf-rbac.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,17 @@ local _M = {

local create_consume_cache
do
local consumer_ids = {}
local consumer_names = {}

function create_consume_cache(consumers)
core.table.clear(consumer_ids)
core.table.clear(consumer_names)

for _, consumer in ipairs(consumers.nodes) do
core.log.info("consumer node: ", core.json.delay_encode(consumer))
consumer_ids[consumer.auth_conf.appid] = consumer
consumer_names[consumer.auth_conf.appid] = consumer
end

return consumer_ids
return consumer_names
end

end -- do
Expand Down
1 change: 0 additions & 1 deletion apisix/schema_def.lua
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,6 @@ _M.service = {
_M.consumer = {
type = "object",
properties = {
id = id_schema,
username = {
type = "string", minLength = 1, maxLength = 32,
pattern = [[^[a-zA-Z0-9_]+$]]
Expand Down
14 changes: 6 additions & 8 deletions doc/admin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,17 +417,17 @@ Return response from etcd currently.

## Consumer

*API*:/apisix/admin/consumers/{id}
*API*:/apisix/admin/consumers/{username}

*Description*:Consumers are consumers of certain types of services and can only be used in conjunction with a user authentication system. Consumer regards the `username` property as the identity, so only the HTTP `PUT` method is supported for creating a new consumer.

> Request Methods:
|Method |Request URI|Request Body|Description |
|---------|-------------------------|--|------|
|GET |/apisix/admin/consumers/{id}|NULL|Fetch resource|
|PUT |/apisix/admin/consumers/{id}|{...}|Create resource by ID|
|DELETE |/apisix/admin/consumers/{id}|NULL|Remove resource|
|GET |/apisix/admin/consumers/{username}|NULL|Fetch resource|
|PUT |/apisix/admin/consumers|{...}|Create resource by username|
|DELETE |/apisix/admin/consumers/{username}|NULL|Remove resource|

> Request Body Parameters:
Expand All @@ -444,7 +444,6 @@ Config Example:

```shell
{
"id": "1", # id
"plugins": {}, # Bound plugin
"username": "name", # Consumer name
"desc": "hello world", # Consumer desc
Expand All @@ -456,9 +455,8 @@ The binding authentication and authorization plug-in is a bit special. When it n
Example:

```shell
$ curl http://127.0.0.1:9080/apisix/admin/consumers/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
$ curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
{
"username": "jack",
"plugins": {
"key-auth": {
"key": "auth-one"
Expand Down Expand Up @@ -511,7 +509,7 @@ In addition to the basic complex equalization algorithm selection, APISIX's Upst
|nodes |required if `k8s_deployment_info` not configured|Hash table, the key of the internal element is the upstream machine address list, the format is `Address + Port`, where the address part can be IP or domain name, such as `192.168.1.100:80`, `foo.com:80`, etc. Value is the weight of the node. In particular, when the weight value is `0`, it has a special meaning, which usually means that the upstream node is invalid and never wants to be selected.|
|k8s_deployment_info|required if `nodes` not configured|fields: `namespace``deploy_name``service_name``port``backend_type`, `port` is number, `backend_type` is `pod` or `service`, others is string. |
|hash_on |optional|This option is only valid if the `type` is `chash`. Supported types `vars`(Nginx variables), `header`(custom header), `cookie`, `consumer`, the default value is `vars`.|
|key |optional|This option is only valid if the `type` is `chash`. Find the corresponding node `id` according to `hash_on` and `key`. When `hash_on` is set as `vars`, `key` is the required parameter, for now, it support nginx built-in variables like `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`, `arg_***` is arguments in the request line, [Nginx variables list](http://nginx.org/en/docs/varindex.html). When `hash_on` is set as `header`, `key` is the required parameter, and `header name` is customized. When `hash_on` is set to `cookie`, `key` is the required parameter, and `cookie name` is customized. When `hash_on` is set to `consumer`, `key` does not need to be set. In this case, the `key` adopted by the hash algorithm is the `consumer_id` authenticated. If the specified `hash_on` and `key` can not fetch values, it will be fetch `remote_addr` by default.|
|key |optional|This option is only valid if the `type` is `chash`. Find the corresponding node `id` according to `hash_on` and `key`. When `hash_on` is set as `vars`, `key` is the required parameter, for now, it support nginx built-in variables like `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`, `arg_***` is arguments in the request line, [Nginx variables list](http://nginx.org/en/docs/varindex.html). When `hash_on` is set as `header`, `key` is the required parameter, and `header name` is customized. When `hash_on` is set to `cookie`, `key` is the required parameter, and `cookie name` is customized. When `hash_on` is set to `consumer`, `key` does not need to be set. In this case, the `key` adopted by the hash algorithm is the `consumer_name` authenticated. If the specified `hash_on` and `key` can not fetch values, it will be fetch `remote_addr` by default.|
|checks |optional|Configure the parameters of the health check. For details, refer to [health-check](health-check.md).|
|retries |optional|Pass the request to the next upstream using the underlying Nginx retry mechanism, the retry mechanism is enabled by default and set the number of retries according to the number of backend nodes. If `retries` option is explicitly set, it will override the default value. `0` means disable retry mechanism.|
|timeout|optional| Set the timeout for connection, sending and receiving messages. |
Expand Down
8 changes: 4 additions & 4 deletions doc/architecture-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ In addition to the basic complex equalization algorithm selection, APISIX's Upst
|service_name |required if `nodes` and `k8s_deployment_info` not configured |The name of the upstream service and used with the registry, refer to [Integration service discovery registry](discovery.md).|
|k8s_deployment_info |required if `nodes` and `service_name` not configured|fields: `namespace``deploy_name``service_name``port``backend_type`, `port` is number, `backend_type` is `pod` or `service`, others is string. |
|hash_on |optional|This option is only valid if the `type` is `chash`. Supported types `vars`(Nginx variables), `header`(custom header), `cookie`, `consumer`, the default value is `vars`.|
|key |required|This option is only valid if the `type` is `chash`. Find the corresponding node `id` according to `hash_on` and `key`. When `hash_on` is set as `vars`, `key` is the required parameter, for now, it support nginx built-in variables like `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`, `arg_***` is arguments in the request line, [Nginx variables list](http://nginx.org/en/docs/varindex.html). When `hash_on` is set as `header`, `key` is the required parameter, and `header name` is customized. When `hash_on` is set to `cookie`, `key` is the required parameter, and `cookie name` is customized. When `hash_on` is set to `consumer`, `key` does not need to be set. In this case, the `key` adopted by the hash algorithm is the `consumer_id` authenticated. If the specified `hash_on` and `key` can not fetch values, it will be fetch `remote_addr` by default.|
|key |required|This option is only valid if the `type` is `chash`. Find the corresponding node `id` according to `hash_on` and `key`. When `hash_on` is set as `vars`, `key` is the required parameter, for now, it support nginx built-in variables like `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`, `arg_***` is arguments in the request line, [Nginx variables list](http://nginx.org/en/docs/varindex.html). When `hash_on` is set as `header`, `key` is the required parameter, and `header name` is customized. When `hash_on` is set to `cookie`, `key` is the required parameter, and `cookie name` is customized. When `hash_on` is set to `consumer`, `key` does not need to be set. In this case, the `key` adopted by the hash algorithm is the `consumer_name` authenticated. If the specified `hash_on` and `key` can not fetch values, it will be fetch `remote_addr` by default.|
|checks |optional|Configure the parameters of the health check. For details, refer to [health-check](health-check.md).|
|retries |optional|Pass the request to the next upstream using the underlying Nginx retry mechanism, the retry mechanism is enabled by default and set the number of retries according to the number of backend nodes. If `retries` option is explicitly set, it will override the default value.|
|timeout|optional| Set the timeout for connection, sending and receiving messages. |
Expand Down Expand Up @@ -415,7 +415,7 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13
}'
```

Test request, the `consumer_id` after authentication is passed will be used as the hash value of the load balancing hash algorithm:
Test request, the `consumer_name` after authentication is passed will be used as the hash value of the load balancing hash algorithm:

```shell
curl http://127.0.0.1:9080/server_port -H "apikey: auth-jack"
Expand Down Expand Up @@ -512,7 +512,7 @@ In APISIX, the process of identifying a Consumer is as follows:
<img src="./images/consumer-internal.png" width="50%" height="50%">

1. Authorization certification: e.g [key-auth](./plugins/key-auth.md), [JWT](./plugins/jwt-auth.md), etc.
2. Get consumer_id: By authorization, you can naturally get the corresponding Consumer `id`, which is the unique identifier of the Consumer object.
2. Get consumer_name: By authorization, you can naturally get the corresponding Consumer `id`, which is the unique identifier of the Consumer object.
3. Get the Plugin or Upstream information bound to the Consumer: Complete the different configurations for different Consumers.

To sum up, Consumer is a consumer of certain types of services and needs to be used in conjunction with the user authentication system.
Expand All @@ -525,7 +525,7 @@ How to enable a specific plugin for a Consumer, you can see the following exampl

```shell
# Create a Consumer, specify the authentication plugin key-auth, and enable the specific plugin limit-count
$ curl http://127.0.0.1:9080/apisix/admin/consumers/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
$ curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"username": "jack",
"plugins": {
Expand Down
Loading

0 comments on commit 1a24c2a

Please sign in to comment.