通过 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;

JWT Auth for Nginx

您可能知道速率限制是通过唯一的 ip 地址应用的,为了获得最佳结果,您应该使用唯一的 jwt 值或令牌来进行速率限制。

您可以按照这 3 种方法中的任何一种进行操作

  1. 方法

可以直接在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;
    }
    ...
}
  1. 方法

您可以在请求 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;
    }
    ...
}
  1. 方法

您可以通过 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;
    }
    ...
}