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

Custom verify function - how? #458

Open jaclas opened 6 months ago

jaclas commented 6 months ago

In the documentation there is repeatedly mentioned about "custom verify function", there are links to the repository, to two issues, etc. I've been looking for several hours for how to use this function and there is no information about it anywhere. No specifics, just generalities. Even the dedicated section "Advanced/Alternative Usage => Bring Your Own verify" has nothing specific, no example, nothing. How to register your own verify function? Please give me one example.

nelsonic commented 6 months ago

A custom verification function is whatever you want it to be. e.g:

if (name === "Bob") {
  verified === true
}

Or whatever you need it to be.

jaclas commented 6 months ago

My question is where to put this code?

I can register the validate function like this:

server.auth.strategy('jwt', 'jwt', true,
{
  key: 'NeverShareYourSecret', 
  validate: myValidateFunction
});

And where to register custom verify function? This is what I can't figure out :-|

nelsonic commented 6 months ago

For an example, please see: https://github.com/dwyl/hapi-auth-jwt2/blob/20969a8d51a0cefa9eb0ce03f2ad5782f3b231cb/test/verify_func_server.js#L20

jaclas commented 6 months ago

Wow! Not a word about this in the documentation:

https://github.com/dwyl/hapi-auth-jwt2?tab=readme-ov-file#documentation

There is also no verify property in the Options interface in the types definitions file (I program in TS):

node_modules/hapi-auth-jwt2/lib/index.d.ts

code:

interface Options {
        /**
         * The secret key used to check the signature of the token *or* a *key lookup function*
         */
        key?: string | string[] | Buffer | ((decodedToken: any) => Promise<{ key: string | string[]; extraInfo?: ExtraInfo }>);

        /**
         * The function which is run once the Token has been decoded
         *
         * @param decoded the *decoded* and *verified* JWT received from the client in *request.headers.authorization*
         * @param request the original *request* received from the client
         */
        validate(decoded: {}, request: Request, tk: ResponseToolkit): ValidationResult | Promise<ValidationResult>;

        /**
         * Settings to define how tokens are verified by the jsonwebtoken library
         */
        verifyOptions?: VerifyOptions;

        /**
         * function called to decorate the response with authentication headers
         * before the response headers or payload is written
         *
         * @param request the Request object
         * @param reply is called if an error occurred
         */
        responseFunc?(request: Request, reply: (err: any, response: ResponseObject) => void): void;

        /**
         *
         * @param ctx called when an error has been raised.
         * @param request the Request object.
         * @param h the ResponseToolkit object.
         * It provides an extension point to allow the host the ability to customise the error messages returned.
         */
        errorFunc?(ctx: ErrorContext, request: Request, h: ResponseToolkit): ErrorContext;

        /**
         * If you prefer to pass your token via url, simply add a token url
         * parameter to your request or use a custom parameter by setting `urlKey.
         * To disable the url parameter set urlKey to `false` or ''.
         * @default 'token'
         */
        urlKey?: string | boolean;

        /**
         * If you prefer to set your own cookie key or your project has a cookie
         * called 'token' for another purpose, you can set a custom key for your
         * cookie by setting `options.cookieKey='yourkeyhere'`. To disable cookies
         * set cookieKey to `false` or ''.
         * @default 'token'
         */
        cookieKey?: string | boolean;

        /**
         * If you want to set a custom key for your header token use the
         * `headerKey` option. To disable header token set headerKey to `false` or
         * ''.
         * @default 'authorization'
         */
        headerKey?: string | boolean;

        /**
         * If you want to set a custom key for your payload token use the
         * `payloadKey` option. To disable payload token set payloadKey to `false` or
         * ''.
         * @default 'token'
         */
        payloadKey?: string | boolean;

        /**
         * Allow custom token type, e.g. `Authorization: <tokenType> 12345678`
         */
        tokenType?: string;

        /**
         * Set to `true` to receive the complete token (`decoded.header`,
         * `decoded.payload` and `decoded.signature`) as decoded argument to key
         * lookup and `verifyFunc` callbacks (*not `validateFunc`*)
         * @default false
         */
        complete?: boolean;

        /**
         * Set to `true` to allow the `payloadFunc` to attempt to extract the token from
         * POST bodies
         * @default false
         */
        attemptToExtractTokenInPayload?: boolean;

        /**
         * Custom token extraction function used to allow consumers to pull tokens from
         * sources not foreseen by the module, for example... YAR
         * @default false
         */
        customExtractionFunc?(request: Request): string;
    }

I haven't yet checked if this will work at all, but it is a heavily hidden thing.

SippieCup commented 3 weeks ago

It works, I have been using it for years.

Strange that it didn't get into the type definitions though.