Coder Social home page Coder Social logo

hapi-now-auth's Introduction

hapi authentication plugin

Hapi Now Auth Test Runner

Note: this plugin is for hapi v17+

This authentication package was inspired by hapi-auth-bearer-token and hapi-auth-jwt2

hapi-now-auth takes care of verifying your JWTs or bearer tokens. We will try to provide the best documentation possible, but reachout should you need help.

Install

You can add the plugin to you project using npm or yarn:
npm:npm i @now-ims/hapi-now-auth
yarn:yarn add @now-ims/hapi-now-auth

Hapi Now Auth Scheme

This plugin creates a hapi-now-auth authentication scheme with the following options:

  • validate - (required) your validation function with [async] function(request, token, h) where:
    • request is the hapi request object
    • token
      • if (verifyJWT === false)
        • the auth token received from the client
      • if (verifyJWT === true)
        • object { decodedJWT, token }
    • h the hapi response toolkit
    • Response
      • { isValid, credentials, artifacts } where:
        • isValid true if JWT or Bearer token is valid
        • credentials an object passed back to your application in request.auth.credentials
        • artifacts optional related data
  • options (Optional)
    • accessTokenName - (Default: 'authorization', Type: string)
    • allowQueryToken - (Default: false, Type: boolean)
    • allowCookieToken - (Default: false, Type: boolean)
    • allowMultipleHeaders - (Default: false, Type: boolean) - accept multiple headers, e.g., Authorization Bearer <token>; Authorization JWT <token>
    • tokenType - (Default: Bearer, Type: string) - accept a custom token type e.g., Authorization JWT <token>
    • allowChaining - (Default: false, Type: boolean) - permit additional authentication strategies
    • unauthorized - (Default: Boom.unauthorized, Type: function) - e.g., function(message, scheme, attributes)
    • verifyJWT - (Default: false, Type: boolean) - verify and decode JWT (note: validate function will need to accept object of { decodedJWT, token })
    • keychain - (Required if verifyJWT: True, Type: array[string]) - an array of your secret keys
    • verifyOptions - (Optional, Type: object)
      • algorithms - (*Default: ['HS256'], Type: array)
      • audience - (Optional, Type: array) - if you want to check the audience aud supply an array to be checked
      • issuer - (Optional, Type: array) - array of strings of valid values for iss field
      • ignoreExpiration - (Default: false, Type: boolean) - ignore exp
      • ignoreNotBefore - (Default: false, Type: boolean) - ignore nbf
      • subject - (Optional, Type: string)
      • clockTolerance - (Optional, Type: integer) - number of seconds to tolerate when checking nbf or exp claims. note: assists with minor clock differences
      • maxAge - (Optional, Type: string) - maximum allowed age for tokens to still be valid - e.g., 2 days, 1 hour, 15m
      • clockTimestamp - the time in seconds that should be used as current time for all necessary comparisons

Working example

const Hapi = require('hapi');
const HapiNowAuth = require('@now-ims/hapi-now-auth');

// create your hapi server
const server = Hapi.server({ port: 8000 });

// Start server function
async function start() {
  // register hapi-now-auth plugin
  try {
    await server.register(HapiNowAuth);
  } catch (error) {
    console.error(error);
    process.exit(1);
  }

  server.auth.strategy('jwt-strategy', 'hapi-now-auth', {
    verifyJWT: true,
    keychain: [process.env.SECRET_KEY],
    validate: async (request, token, h) => {
      let isValid, artifacts;

      /**
       * we asked the plugin to verify the JWT
       * we will get back the decodedJWT as token.decodedJWT
       * and we will get the JWT as token.token
       */

      const credentials = token.decodedJWT;

      /**
       * return the decodedJWT to take advantage of hapi's
       * route authentication options
       * https://hapijs.com/api#authentication-options
       */

      /**
       * Validate your token here
       * For example, compare to your redis store
       */

      redis.get(token, (error, result) => {
        if (error) {
          isValid = false;
          artifacts.error = error;
          return { isValid, credentials, artifacts };
        }
        isValid = true;
        artifacts.info = result;
        return { isValid, credentials, artifacts };
      });
    },
  });

  server.auth.default('jwt-strategy');

  server.route({
    method: 'GET',
    path: '/',
    handler: async (request, h) => {
      return { info: 'success!' };
    },
    options: {
      auth: false,
    },
  });

  server.route({
    method: 'GET',
    path: '/protected',
    handler: async (request, h) => {
      return { info: 'success if JWT is verified!' };
    },
  });

  server.route({
    method: 'GET',
    path: '/admin',
    handler: async (request, h) => {
      return { info: 'success if JWT is verified and scope includes admin' };
    },
    options: {
      auth: {
        scope: 'admin',
      },
    },
  });

  try {
    await server.start();
  } catch (error) {
    console.error(error);
    process.exit(1);
  }

  console.log(`Server running at: ${server.info.uri}`);
}

// Don't worry be hapi
start();

Acknowledgement

This project is kindly sponsored by Now IMS

Licensed under MIT

hapi-now-auth's People

Contributors

artentica avatar dependabot[bot] avatar iniva avatar jeremylorino avatar marcuspoehls avatar puchesjr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

hapi-now-auth's Issues

Remove nsp dependency

The Node Security Platform was acquired by NPM earlier this year and today (September 30) reached its end of life cycle.

Since the functionality was adopted by NPM itself, nsp can be removed as a dependency.

Pass through error messages for failed JWT verification

At this point, hapi-now-auth eats all error messages. I guess this behavior is intended to rely on hapi’s default Missing authentication error message.

Would you consider passing error messages through from the JWT verify method call? Your current code looks like this:

try {
  ++keysTried
  decodedJWT = JWT.verify(token, k, settings.verifyOptions)
  return true
} catch (error) {
  if (keysTried >= settings.keychain.length) {
    throw settings.unauthorized(null, settings.tokenType)   // <-- this line here
  }
  return false
}

Passing the error message to settings.unauthorized would help to provide better error feedback to requesting clients. Missing authentication doesn’t help to find out that the token expired.

An idea could be to pass through the message if there’s a custom unauthorized and not the one from defaults.

What do you think about this idea?

Add JWT Signing

Would you like to see JWT Signing from this plugin?

Why or why not?

How to generate a token

Hi,

The readme includes an example on how to verify a token. How do I generate a token after successful login?

How do I use RS256 signed token with this package?

I'm required to use RS256 for a project.

there will be jwks endpoint like this https://domain-name.auth0.com/.well-known/jwks.json

I tried to pass the key from jwksUri into the the strategy options like following, it doesn't work, how should I use RS256 signed JWT here?

server.auth.strategy('jwt', 'hapi-now-auth', {
    verifyJWT: true,
    keychain: [jwksRsa.hapiJwt2Key({
      cache: true,
      jwksUri,
    })],
    verifyOptions: {
      algorithms: ['RS256']
      audience,
    },
    validate: async (req, token, h) => {}
    ...

Explicit "Token expired" error message

Hey friends,

thank you for your recent changes on hapi-now-auth and passing through error messages.

Is there a chance the explicitly know if a token is expired?
I’d like to tell users that they have to renew the token. The current error message is this: Invalid JWT: key or signature is invalid.

The current error message is correct. I’m just looking for a detailed error message besides the general "is invalid" for expired tokens.

Do you think there’s a chance to add that?

Dependency on @hapi/joi is causing issues now that Joi has broken off of Hapi

The joi project is no longer maintained within the Hapi project. It is now in its own namespace. https://joi.dev/

As a result, when using hapi v20+ you must include both @hapi/joi (which is stale) and joi in your project dependencies to get @now-ims/hapi-auth-now to work. The project doesn't appear to list @hapi/joi as a dependency and this has led to build failures and workarounds.

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.