通过来自 JWT 令牌的解码值限制 NGINX 速率

Mar*_*ski 6 nginx rate-limiting luajit openresty

我有一个关于 NGINX 速率限制的问题。

是否可以根据 JWT 令牌的解码值进行速率限制?我在文档中找不到任何这样的信息。

或者,即使有一种通过创建纯自定义变量(使用 LuaJIT)来限制速率的方法,该变量将从我解码的 JWT 中分配一个值 - 也可以完成这项工作。问题是limit_req模块似乎在请求到达 luaJIT 阶段之前执行,所以已经太晚了!

一个解决方案将不胜感激。

Cha*_*dan 7

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

您可以遵循这 3 种方法中的任何一种

  1. 方法

您可以直接在 limit_req_zone 中使用 jwt 令牌。

http {
    ...
    limit_req_zone $http_authorization zone=req_zone:10m rate=5r/s;
}
Run Code Online (Sandbox Code Playgroud)

conf.d/默认.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;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)
  1. 方法

您可以在请求标头中从前端发送解码后的 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;
}
Run Code Online (Sandbox Code Playgroud)

conf.d/默认.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;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)
  1. 方法

您可以通过 njs javascript 模块或 perl 模块或 lua 模块解码 nginx 中的 jwt 令牌并将其分配给变量,然后使用它来进行速率限制。

描述:这里我刚刚解码了 jwt 值并检查它是否不为空,您可以使用它来处理 jwt 解码值。

jwt_example.js

http {
    ...
    limit_req_zone $http_authorization zone=req_zone:10m rate=5r/s;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

conf.d/默认.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;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)