hapi - How to Fix „unknown authentication strategy“

For web based applications, there are various authentication mechanisms available. To let your hapi server support a selected one, pick a plugin from the hapi ecosystem, provide the required configuration and you’re ready to go.

At some point, most of us hapi developers trap into an unknown authentication strategy <name> in <route-path> error and didn’t realize why this occurs.

Actually, the fix is kind of straight forward. Read on to get the details!

hapi Series Overview

The Problem

Independent of your app’s authentication strategy, the following error stack trace probably feels familiar:

$ node server.js

/Users/marcuspoehls/Dev/JS/nodejs-tutorials-hapi/node_modules/hapi/node_modules/hoek/lib/index.js:736
    throw new Error(msgs.join(' ') || 'Unknown error');
    ^

Error: Unknown authentication strategy session in /  
    at Object.exports.assert (/Users/marcuspoehls/Dev/JS/nodejs-tutorials-hapi/node_modules/hapi/node_modules/hoek/lib/index.js:736:11)
    …

In essence, the defined authentication strategy called session is not available for the route with path /. Now you might think that you’re creating the session strategy in your project and hapi still can’t find it. So what’s the issue?

The Solution(s)

The actual problem is that the session strategy is created too late. A route that requires the session strategy is registered before session is known to the server.

Now that you know the problem (a strategy not created when the route with related authentication scheme should be registered), you can put your solution in place. Depending on your application setup, there are different approaches on how to implement the solution.

Create a Dedicated Authentication Plugin

Composing your application with individual plugins is the recommended way in hapi. If you’re already splitting the different parts of your apps into separate plugins, there’s a straightforward way to fix the problem: create a dedicated authentication plugin.

Create the Plugin

The following snippet illustrates the authentication plugin by using the hapi-auth-cookie dependency to create the session strategy.

Let’s name the following snippet authentication.js, so we can easily refer to it:

authentication.js

const Hoek = require('hoek')

async function register (server, options) {  
  // register dependency to hapi-auth-cookie
  // and make sure it’s available to this plugin
  await server.register({
    plugin: require('hapi-auth-cookie')
  })

  // configure the "session" strategy
  server.auth.strategy('session', 'cookie', {
    password: 'ThisIsASecretPasswordForTheAuthCookie',
    redirectTo: '/',
    isSecure: process.env.NODE_ENV === 'production'
  })
}

exports.plugin = {  
  register,
  name: 'authentication',
  version: '1.0.0',
  once: true
}

The code snippet above uses the hapi-auth-cookie module as a dependency. Also, this specific authentication plugin (see the plugin’s name attribute) registers its dependencies itself. Please make sure you don’t register the hapi-auth-cookie twice to your hapi server, then you’ll get an error.

Notice the once: true within the plugin’s attributes. This configuration tells hapi to register this plugin only once on the same server.

What about server.dependency?

Did you think about using server.dependency([ 'hapi-auth-cookie' ]) to declare the dependency between authentication and hapi-auth-cookie (or further plugins)?

Sadly, hapi doesn’t make sure that plugins are registered in order and therefore you need to make sure the hapi-auth-cookie plugin is definitely registered before authentication should be plugged into your server.

Now that you’ve set the dependency within your authentication plugin, go ahead and create the session strategy based on the cookie scheme. You need to do that within the callback function of server.register().

With the call of next(), hapi knows that your plugin is registered and the next one can be processed.

Use Authentication Plugin in Your App

In your plugins that require authentication and specifically the session strategy, register the authentication plugin (from the code block above) as a dependency.

The authentication plugin is your custom one (from the code block above, which we named authentication.js). Of course, you can name it whatever you want :)

Let’s name the following snippet your-plugin.js to get a reference within this tutorial.

your-plugin.js

async function register (server, options) {  
  await server.register([
    {
      register: require('./path/to/authentication')
    }
    {
      register: require('vision') // if you want view rendering support
    },
  ])

  // your plugin logic goes here
  // like "server.route(yourRoutes)"

  // tell hapi it’s safe to process the next plugin :)
}

Within your application plugins that rely on the authentication plugin as a dependency, make sure you install it. The once: true attribute of authentication makes sure hapi only registers the plugin once for the same server.

Having the dependencies installed, do your individual configuration, add routes, extend the request lifecycle, etc.

Register Plugins to Your Server

The dedicated authentication plugin is a requirement for other plugins. Individual plugins should make sure their dependencies are installed by doing it themselves.

That’s why you only need to register your “main” plugins and they individually handle their dependencies themselves.

const Hapi = require('hapi')  
const server = new Hapi.Server()

// register plugins to server instance
async function liftOff () {  
  server.register([
    {
      plugin: require('./path/to/your-plugin')
    },
    {
      plugin: require('./path/to/another-plugin')
    },
    {
      plugin: require('./path/to/the-fancy-funky-plugin')
    }
  ])

  try {
    await server.start()
    console.log('Server running at: ' + server.info.uri)
  } catch (err) {
    console.log(err)
    process.exit(1)
  }
}

liftOff()  

Not Using Plugins: Ensure a Server Composition Flow

If you don’t compose your hapi app with individual plugins, make sure that you register the used plugins (e.g., vision, inert, etc.) first. Then create the authentication strategies, set the view configuration or do everything else you want to use in your routes.

Having the plugins registered, views configured or authentication in place, register all your routes to the hapi server instance. Adding the routes to the hapi server with (all batteries included) should go well.

Outlook

In this tutorial you’ve learned how to fix the actual problem for the „unknown authentication strategy“ error. This error occurs, because the given strategy is not available to the server yet while a route should be added and requires the strategy.

Solve this problem by creating a dedicated authentication plugin that can be defined as a dependency for your individual application plugins. If you don’t use plugins to compose your app, make sure your application flow follows the correct path of registering dependencies first, configure the authentication strategies and than add routes.

Want to learn more on how to access and handle the request payload in hapi? The linked tutorial is for you!

We’re happy to hear your thoughts and comments. Please don’t hesitate to use the comments below or find us on Twitter @futurestud_io. Let us know what you think!

Enjoy coding & make it rock!

Explore the Library

Find interesting tutorials and solutions for your problems.