通过 JWT 令牌的解码值限制 NGINX 速率
NGINX rate limitting by decoded values from JWT token
我有一个关于 NGINX 速率限制的问题。
是否可以根据JWT token的解码值做限速?我在文档中找不到任何此类信息。
或者即使有一种通过创建纯自定义变量(使用 LuaJIT)来进行速率限制的方法,该变量将从我解码的 JWT 中分配一个值 - 也可以完成这项工作。
问题是 limit_req
模块似乎在请求到达 luaJIT 阶段之前执行,所以已经太晚了!
将不胜感激。
Nginx 的 JWT 验证
nginx-jwt
是 Nginx 服务器的 Lua 脚本(运行 宁 HttpLuaModule
),它将允许您使用 Nginx 作为反向代理您现有的 HTTP 服务集,并在授权请求 header 中使用受信任的 JSON Web 令牌 (JWT) 保护它们 (authentication/authorization),而无需对支持服务进行少量更改或不进行任何更改他们自己。
重要提示: nginx-jwt
是一个 Lua 脚本,旨在 运行 在具有 HttpLuaModule
的 Nginx 服务器上安装。但最终它的依赖项需要 Nginx OpenResty
发行版中可用的组件。因此,建议您使用 OpenResty
作为您的 Nginx 服务器,并且这些说明做出了该假设。
配置
目前,nginx-jwt 仅支持对称密钥 (alg = hs256),这就是为什么您需要使用下面的共享 JWT 密钥配置您的服务器。
1.Export Nginx 主机上的 JWT_SECRET 环境变量,将其设置为您的 JWT 密码。然后将其暴露给 Nginx 服务器:
# nginx.conf:
env JWT_SECRET;
2.If 你的 JWT 密码是 Base64 (URL-safe) 编码的,导出 Nginx 主机上的 JWT_SECRET_IS_BASE64_ENCODED 环境变量,将其设置为 true。然后将其暴露给 Nginx 服务器:
# nginx.conf:
env JWT_SECRET_IS_BASE64_ENCODED;
您可能知道速率限制是通过唯一的 ip 地址应用的,为了获得最佳结果,您应该使用唯一的 jwt 值或令牌来进行速率限制。
您可以按照这 3 种方法中的任何一种进行操作
- 方法
可以直接在limit_req_zone中使用jwt token。
http {
...
limit_req_zone $http_authorization zone=req_zone:10m rate=5r/s;
}
conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
if ($http_authorization = "") {
return 403;
}
location /jwt {
limit_req zone=req_zone burst=10 nodelay;
return 200 $http_authorization;
}
...
}
- 方法
您可以在请求 header 中从前端发送解码后的 jwt 值,例如 http_x_jwt_decode_value,然后您可以在 limit_req_zone.
中使用它
http {
...
limit_req_zone $http_x_jwt_decode_value zone=req_zone:10m rate=5r/s;
}
conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
if ($http_x_jwt_decode_value = "") {
return 403;
}
location /jwt {
limit_req zone=req_zone burst=10 nodelay;
return 200 $http_x_jwt_decode_value;
}
...
}
- 方法
您可以通过 njs javascript 模块或 perl 模块或 lua 模块在 nginx 中解码 jwt 令牌并将其分配给变量然后使用它来限制速率。
描述: 这里我刚刚解码了 jwt 值并检查它是否不为空你可以使用它来处理和 jwt 解码值。
jwt_example.js
function jwt(data) {
var parts = data.split('.').slice(0,2)
.map(v=>String.bytesFrom(v, 'base64url'))
.map(JSON.parse);
return { headers:parts[0], payload: parts[1] };
}
function jwt_payload_sub(r) {
return jwt(r.headersIn.Authorization.slice(7)).payload.sub;
}
export default {jwt_payload_sub}
nginx.conf
# njs module
load_module modules/ngx_http_js_module.so;
http {
...
include /etc/nginx/conf.d/*.conf;
js_import main from jwt_example.js;
js_set $jwt_payload_sub main.jwt_payload_sub;
limit_req_zone $jwt_payload_sub zone=req_zone:10m rate=5r/s;
}
conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
if ($jwt_payload_sub = "") {
return 403;
}
location /jwt {
limit_req zone=req_zone burst=10 nodelay;
return 200 $jwt_payload_sub;
}
...
}
我有一个关于 NGINX 速率限制的问题。
是否可以根据JWT token的解码值做限速?我在文档中找不到任何此类信息。
或者即使有一种通过创建纯自定义变量(使用 LuaJIT)来进行速率限制的方法,该变量将从我解码的 JWT 中分配一个值 - 也可以完成这项工作。
问题是 limit_req
模块似乎在请求到达 luaJIT 阶段之前执行,所以已经太晚了!
将不胜感激。
Nginx 的 JWT 验证
nginx-jwt
是 Nginx 服务器的 Lua 脚本(运行 宁 HttpLuaModule
),它将允许您使用 Nginx 作为反向代理您现有的 HTTP 服务集,并在授权请求 header 中使用受信任的 JSON Web 令牌 (JWT) 保护它们 (authentication/authorization),而无需对支持服务进行少量更改或不进行任何更改他们自己。
重要提示: nginx-jwt
是一个 Lua 脚本,旨在 运行 在具有 HttpLuaModule
的 Nginx 服务器上安装。但最终它的依赖项需要 Nginx OpenResty
发行版中可用的组件。因此,建议您使用 OpenResty
作为您的 Nginx 服务器,并且这些说明做出了该假设。
配置
目前,nginx-jwt 仅支持对称密钥 (alg = hs256),这就是为什么您需要使用下面的共享 JWT 密钥配置您的服务器。
1.Export Nginx 主机上的 JWT_SECRET 环境变量,将其设置为您的 JWT 密码。然后将其暴露给 Nginx 服务器:
# nginx.conf:
env JWT_SECRET;
2.If 你的 JWT 密码是 Base64 (URL-safe) 编码的,导出 Nginx 主机上的 JWT_SECRET_IS_BASE64_ENCODED 环境变量,将其设置为 true。然后将其暴露给 Nginx 服务器:
# nginx.conf:
env JWT_SECRET_IS_BASE64_ENCODED;
您可能知道速率限制是通过唯一的 ip 地址应用的,为了获得最佳结果,您应该使用唯一的 jwt 值或令牌来进行速率限制。
您可以按照这 3 种方法中的任何一种进行操作
- 方法
可以直接在limit_req_zone中使用jwt token。
http {
...
limit_req_zone $http_authorization zone=req_zone:10m rate=5r/s;
}
conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
if ($http_authorization = "") {
return 403;
}
location /jwt {
limit_req zone=req_zone burst=10 nodelay;
return 200 $http_authorization;
}
...
}
- 方法
您可以在请求 header 中从前端发送解码后的 jwt 值,例如 http_x_jwt_decode_value,然后您可以在 limit_req_zone.
中使用它http {
...
limit_req_zone $http_x_jwt_decode_value zone=req_zone:10m rate=5r/s;
}
conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
if ($http_x_jwt_decode_value = "") {
return 403;
}
location /jwt {
limit_req zone=req_zone burst=10 nodelay;
return 200 $http_x_jwt_decode_value;
}
...
}
- 方法
您可以通过 njs javascript 模块或 perl 模块或 lua 模块在 nginx 中解码 jwt 令牌并将其分配给变量然后使用它来限制速率。
描述: 这里我刚刚解码了 jwt 值并检查它是否不为空你可以使用它来处理和 jwt 解码值。
jwt_example.js
function jwt(data) {
var parts = data.split('.').slice(0,2)
.map(v=>String.bytesFrom(v, 'base64url'))
.map(JSON.parse);
return { headers:parts[0], payload: parts[1] };
}
function jwt_payload_sub(r) {
return jwt(r.headersIn.Authorization.slice(7)).payload.sub;
}
export default {jwt_payload_sub}
nginx.conf
# njs module
load_module modules/ngx_http_js_module.so;
http {
...
include /etc/nginx/conf.d/*.conf;
js_import main from jwt_example.js;
js_set $jwt_payload_sub main.jwt_payload_sub;
limit_req_zone $jwt_payload_sub zone=req_zone:10m rate=5r/s;
}
conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
if ($jwt_payload_sub = "") {
return 403;
}
location /jwt {
limit_req zone=req_zone burst=10 nodelay;
return 200 $jwt_payload_sub;
}
...
}