dwyl / hapi-auth-jwt2

:lock: Secure Hapi.js authentication plugin using JSON Web Tokens (JWT) in Headers, URL or Cookies
ISC License
798 stars 126 forks source link

invoking hapi.auth.verify does not execute the custom verify function #317

Open abillingsley opened 5 years ago

abillingsley commented 5 years ago

The following issue was discovered while troubleshooting the behavior identified in https://github.com/hapijs/nes/issues/292

I have a hapi server implementation which leverages hapi-auth-jwt2 as the default auth strategy. In this auth strategy, I have configured a custom verify function

I take all the defaults when configuring the plugin

{
    plugin: require("hapi-auth-jwt2"),
}

configuration when defining the strategy

await this.server.auth.strategy("jwt", "jwt", {
  verify: async (decoded: IDecodedToken, request: Request) => {
    // custom logic here
  },
  tokenType: "bearer",
  complete: true,
});
this.server.auth.default("jwt");

as part of the auth interface provided by the hapi server a verify method exists. hapi nes and presumably other libraries rely on this interface to verify authentication. https://github.com/hapijs/hapi/blob/master/lib/auth.js#L100

this method finds the auth strategy. If the auth stategy defined a verify method like hapi-auth-jwt2 does the verify method will be invoked https://github.com/hapijs/hapi/blob/master/lib/auth.js#L120

In the case of hapi-auth-jwt2 the invocation of this verify method calls https://github.com/dwyl/hapi-auth-jwt2/blob/master/lib/index.js#L295

This method does some default verification of JWT which probably works perfectly if you are not using a customVerify function. In my case my customVerify function does not leverage a public key for verification and as a result this method is unable to verify the provided jwt token. As a result the secret or public key must be provided is thrown.

I think I expect the verify function defined in https://github.com/dwyl/hapi-auth-jwt2/blob/master/lib/index.js#L295 to execute options.verify if provided.

maybe something like

verify: async function(auth) {
   const token = auth.artifacts;
   const decoded = JWT.decode(token, {
     complete: options.complete || false,
   });
   if (options.verify) {
     // verify using the provided function
     options.verify(decoded, /*not sure what to do about request*/);
   } else {
      const { keys } = await internals.getKeys(decoded, options);
      internals.verifyJwt(token, keys, options);
   }
},
nelsonic commented 3 years ago

Worth re-visiting this in light of updates made to plugin. 💭