Giter Club home page Giter Club logo

Comments (12)

max-lt avatar max-lt commented on July 25, 2024 3

Hi guys, it's merged and published under v3.2.2

from nginx-jwt-module.

mechanical-rus528 avatar mechanical-rus528 commented on July 25, 2024 1

Note that a map didn't do anything to help the situation. When doing

map $jwt_claim_id $mapped_id {
  "dummy" 0;
  default $jwt_claim_id;
}
add_header X-MAPPED-ID $mapped_id always;

the header is never there. So it seems like $jwt_claim_id is not yet set when the map is executed? Though I might be misunderstanding how nginx works.

from nginx-jwt-module.

max-lt avatar max-lt commented on July 25, 2024

Hello, sorry for the late response,
I will dig into it,
my first guess would be about mdule ordering, the req limit module may be called before the jwt one so $jwt_claim_id is null when evaluating, but it's surprising.

Could you debug by sending back a header with jwt_claim_id to ensure it's set in context ?
add_header X-JWT-ID $jwt_claim_id always;

from nginx-jwt-module.

max-lt avatar max-lt commented on July 25, 2024

After some thinking I think you almost found the solution yourself,
the solution is to use a map like you did because $jwt_claim_id will only be set while reading a JWT token (so at runtime),
you need to set a map to bind $jwt_claim_id to a default value if not defined yet for the limit_req_zone directive.

 map $jwt_claim_id $lreq_user_key {
    "" 1;
    default $jwt_claim_id;
  }

This should tell limit_req_zone to use $lreq_user_key variable, set to 1 if $jwt_claim_id is unset (config time) and $jwt_claim_id when reading a JWT that has a id property.

from nginx-jwt-module.

zil1 avatar zil1 commented on July 25, 2024

Sorry, I misunderstood how the req limit module works, and misled.
We are trying to set a limit for a specific user:

  map $jwt_claim_id $lreq_user_key {
      \"100172\" $jwt_claim_id;
      default "";
  }

I added header:
add_header X-JWT-ID $lreq_user_key always;

I get the correct header value, but if I add limit_req_zone for this variable, then I don't get a header.

http {
...
  map $jwt_claim_id $lreq_user_key {
      \"100172\" $jwt_claim_id;
      default "";
  }

  limit_req_zone $lreq_user_key zone=lreq_user:10m rate=1r/m;
  ...
  server {
    auth_jwt off;
    auth_jwt_key /etc/nginx/certs/jwt.pem file;
    ...
    location /api/ {
      auth_jwt on;
      limit_req zone=lreq_user;
      ...
    }
  }
}

At the same time, jwt authorization works

from nginx-jwt-module.

max-lt avatar max-lt commented on July 25, 2024

If limit_req_zone returns no header it may be matching the default (empty string) value, try

map $jwt_claim_id $lreq_user_key {
      \"100172\" $jwt_claim_id;
      default "default_zone";
  }

to check.

Is your jwt id (jwt_claim_id) a string or a number ?

from nginx-jwt-module.

mechanical-rus528 avatar mechanical-rus528 commented on July 25, 2024

I've run into a similar problem with limit_conn_zone. Using something like:

limit_conn_zone $jwt_claim_id zone=id:10m;

server {
  limit_conn id 1;
}

does not actually limit the number of connections.

Using add_header X-JWT-ID $jwt_claim_id always; does return the expected ID, so I think your guess about module ordering might be right. Perhaps using ngx_module_order in config will help?

from nginx-jwt-module.

max-lt avatar max-lt commented on July 25, 2024

I can reproduce with

Config:

limit_req_zone $mapped_id zone=lreq_user:10m rate=1r/m;

map $jwt_claim_id $mapped_id {
  default       $jwt_claim_id;
  ""            "not-set";
}

server {
  // ...

  location = /limit-req {
    auth_jwt_key 'secret' utf8;

    add_header X-MAPPED-ID $mapped_id always;
    add_header X-JWT-ID $jwt_claim_id always;

    limit_req zone=lreq_user burst=1 nodelay;

    try_files _ =201;
  }
  // ...
}

JWT data:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "id": 123456
}

Encoded

export JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJpZCI6MTIzNDU2fQ.2CstE0GAwt2nkyOfc4rtqZJsyYzpBipOQf_dij9NGc4
make test-image
docker run --rm --name jwt-nginx-test -p 8000:8000 jwt-nginx-test
curl -v localhost:8000/limit-req --header "Authorization: Bearer ${JWT}"

Call return when the server limit_req directive is set:

< X-MAPPED-ID: not-set
< X-JWT-ID: 123456

Call return when the server limit_req directive is not set:

< X-MAPPED-ID: 123456
< X-JWT-ID: 123456

I will look if it's possible to choose modue order (may gives hints for #1 too).

from nginx-jwt-module.

max-lt avatar max-lt commented on July 25, 2024

Ok I've dug it a bit, so we can register module phases, this module is in NGX_HTTP_ACCESS_PHASE which is one phase after NGX_HTTP_PREACCESS_PHASE (phase for ngx_http_limit_conn_module and ngx_http_limit_req_module).

I think the best way is to execute the variable operations in one of the early phases and keep the JWT check in the access phase.

from nginx-jwt-module.

max-lt avatar max-lt commented on July 25, 2024

It works on this branch. I'll do some more checks but it should be merged soon.

from nginx-jwt-module.

mechanical-rus528 avatar mechanical-rus528 commented on July 25, 2024

Fantastic! Nice digging, and I really appreciate you looking into this. <3

from nginx-jwt-module.

zil1 avatar zil1 commented on July 25, 2024

it works, thanks!

from nginx-jwt-module.

Related Issues (17)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.