auth0 / express-jwt

connect/express middleware that validates a JsonWebToken (JWT) and set the req.user with the attributes
MIT License
4.49k stars 444 forks source link

How to verify a signed JWT using JWKs #166

Open neocolmartin opened 7 years ago

neocolmartin commented 7 years ago

The README describes how to validate a JWT against a secret or a public key. However, when I try to do the same but using a JWK JSON object for an RSA key, I get an error.

Pull request #75 suggests that JWK keys are supported, but I can't get it to work.

This is my code:

...

var keys = [{"alg":"RS256","e":"AQAB","n":"6A2sxWzCc0kDpRxOa6kj1XK2FQFq0WFs-bn_pwiEkDTQea4m06XyXBoP1Y89u7cIhVJtm7Nr_TKR-stdp5MmzzKm4Tu-YbpsMvDmeqyxnmcKPzsKqavOBV5uK1_TsWGLYDBuGLwJ8uuSgJFvcOWbIsgKogGftX_aSPhEWSYzLY06YrO6-Kv_sjhcISf01I8E2tNGlmN2ngf95q7H4jDzU_leijC-BCUcuMqQVpbWR0vElTi8JyHKO0TQFN2JkILr-VBFYNt6_G2Fe7TB0LyJDHsg2f02nI9Au8gLz1rJZkdJAs2pG8UqzTObjyUuxb5CT9FPMqtXgZeDf5CT037e-w","kid":"CYcvHlf_jYo73BNke3kRovuwXUdT-1cvQBAQuDTqS8s","kty":"RSA","use":"sig"},{"alg":"RS256","e":"AQAB","n":"kAwmgEKtYUkPXYpdOAaH1UumWqU-gE1FW_r0nq_LyTqkTRgakkb59F0SiMqJbee8xqToJrGVbQvzHWdYEkqLQPR2yPu0fsk71AT2XKfNr3c6buiNCK1ibyFqg7ApJrmjtgORcQogi421Sjhx1ZqtPUSFg7hQtlmv9pRTuf3Oe-5oJsR6D_bCFXNoiTj6my-MTJzVp6Bw4M_Tic2K6xBnHpIeHzhXr_p5Ww9m8uW0vLHLlii5CqhaWZNHTB_OfKQYG30WzAOIAXeZNVXmkCFoA91gUe-PjSCM6Z-y_SnKcZX94d9ScCc_Tdixv93zFVejXo6pLHobzdUTeh8xUD4TDQ","kid":"NKx76iKoxcBNeeXKpfZYmxL0uvanvuGSnBFUb6XwpDo","kty":"RSA","use":"sig"}];

app.get(
  '/',
  jwt(
    {
      // algorithms: [ 'RS256','RS384','RS512','ES256','ES384','ES512' ],
      secret: (req, header, payload, done) => {
        var key = provider.jwks.find(key => key.kid == header.kid);
        done(null, key);
      }
    }
  ),
  function (req, res) {
    // ...
  }
);

var port = 8080;
app.listen(port, function () {
  console.log('App listening on '+port);
});

Running the code above, and sending in a request with an Authorization: Bearer header containing a valid JWT, I get this error:

UnauthorizedError: invalid algorithm
    at /home/martin/src/proto/node-verifier/node_modules/express-jwt/lib/index.js:102:22
    at /home/martin/src/proto/node-verifier/node_modules/jsonwebtoken/verify.js:27:18
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

If I uncomment the algorithms key (and restart node) and send the request again, I then get this error:

UnauthorizedError: key must be a string or a buffer
    at /home/martin/src/proto/node-verifier/node_modules/express-jwt/lib/index.js:102:22
    at /home/martin/src/proto/node-verifier/node_modules/jsonwebtoken/verify.js:27:18
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

If I try JSON.stringify(key) instead, I get this error:

UnauthorizedError: PEM_read_bio_PUBKEY failed
    at /home/martin/src/cbc/proto/node-verifier/node_modules/express-jwt/lib/index.js:102:22
    at /home/martin/src/cbc/proto/node-verifier/node_modules/jsonwebtoken/verify.js:27:18
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

Are JWK keys supported? If so, how do I use them for validation?

neocolmartin commented 7 years ago

Someone elsewhere pointed me to the jwks-rsa package that provides a way to look up JWK keys for express-jwt: https://github.com/auth0/node-jwks-rsa/tree/master/examples/express-demo

juanslingerURUIT commented 5 years ago

After 2 years, this solution works excellent for me. Thanks @neocolmartin 👏 . Don't know why is so complicated to just use express-jwt by his own.

shoaib30 commented 3 years ago

4 years later, still helpful. It may be useful to add the link/ example to docs on this repo