As you may know that rate limit is applied through unique ip address for best result you should use unique jwt value or token to rate limit.
You can follow any of these 3 methods
- Method
You can directly use jwt token in limit_req_zone.
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;
}
...
}
- Method
You can send decoded jwt value from frontend in reqest header like http_x_jwt_decode_value and then you can use that in 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;
}
...
}
- Method
You can decode jwt token in nginx though njs javascript module or perl module or lua module and assign it to variable then use that to rate limit.
Description: here i just decoded jwt value and checked if its not empty you can use it to work with and jwt decoded value.
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;
}
...
}