The last tutorials within this hapi series walked you through the details of basic authentication with hapi and how to remember users leveraging cookies and also how to explicitly set a default authentication strategy.
Within this guide, you’ll learn how to allow multiple authentication strategies for individual routes.
Before diving into the details, have a look at the series outline and find posts that match your interests and needs.
hapi Series Overview
- What You’ll Build
- Prepare Your Project: Stack & Structure
- Environment Variables and Storing Secrets
- Set Up MongoDB and Connect With Mongoose
- Sending Emails in Node.js
- Load the User’s Profile Picture From Gravatar Using Virtuals in Mongoose
- Implement a User Profile Editing Screen
- Generate a Username in Mongoose Middleware
- Displaying Seasons and Episodes for TV Shows with Mongoose Relationship Population
- Implementing Pagination for Movies
- Implement a Watchlist
- Create a Full Text Search with MongoDB
- Create a REST API with JSON Endpoints
- Update Mongoose Models for JSON Responses
- API Pagination for TV Shows
- Customize API Endpoints with Query Parameters
- Always Throw and Handle API Validation Errors
- Advanced API Validation With Custom Errors
- Create an API Documentation with Swagger
- Customize Your Swagger API Documentation URL
- Describe Endpoint Details in Your Swagger API Documentation
- 10 Tips on API Testing With Postman
- JWT Authentication in Swagger API Documentation
- API Versioning with Request Headers
- API Login With Username and Password to Generate a JWT
- JWT Authentication and Private API Endpoints
- Refresh Tokens With JWT Authentication
- Create a JWT Utility
- JWT Refresh Token for Multiple Devices
- Check Refresh Token in Authentication Strategy
- Rate Limit Your Refresh Token API Endpoint
- How to Revoke a JWT
- Invalidate JWTs With Blacklists
- JWT Logout (Part 1/2)
- JWT “Immediate” Logout (Part 2/2)
- A Better Place to Invalidate Tokens
- How to Switch the JWT Signing Algorithm
- Roll Your Own Refresh Token Authentication Scheme
- JWT Claims 101
- Use JWT With Asymmetric Signatures (RS256 & Co.)
- Encrypt the JWT Payload (The Simple Way)
- Increase JWT Security Beyond the Signature
- Unsigned JSON Web Tokens (Unsecured JWS)
- JWK and JWKS Overview
- Provide a JWKS API Endpoint
- Create a JWK from a Shared Secret
- JWT Verification via JWKS API Endpoint
- What is JOSE in JWT
- Encrypt a JWT (the JWE Way)
- Authenticate Encrypted JWTs (JWE)
- Encrypted and Signed JWT (Nested JWT)
- Bringing Back JWT Decoding and Authentication
- Bringing Back JWT Claims in the JWT Payload
- Basic Authentication With Username and Password
- Authentication and Remember Me Using Cookies
- How to Set a Default Authentication Strategy
- Define Multiple Authentication Strategies for a Route
- Restrict User Access With Scopes
- Show „Insufficient Scope“ View for Routes With Restricted Access
- Access Restriction With Dynamic and Advanced Scopes
- hapi - How to Fix „unknown authentication strategy“
- Authenticate with GitHub And Remember the Login
- Authenticate with GitLab And Remember the User
- How to Combine Bell With Another Authentication Strategy
- Custom OAuth Bell Strategy to Connect With any Server
- Redirect to Previous Page After Login
- How to Implement a Complete Sign Up Flow With Email and Password
- How to Implement a Complete Login Flow
- Implement a Password-Reset Flow
- Views in hapi 9 (and above)
- How to Render and Reply Views
- How to Reply and Render Pug Views (Using Pug 2.0)
- How to Create a Dynamic Handlebars Layout Template
- Create and Use Handlebars Partial Views
- Create and Use Custom Handlebars Helpers
- Specify a Different Handlebars Layout for a Specific View
- How to Create Jade-Like Layout Blocks in Handlebars
- Use Vue.js Mustache Tags in Handlebars Templates
- How to Use Multiple Handlebars Layouts
- How to Access and Handle Request Payload
- Access Request Headers
- How to Manage Cookies and HTTP States Across Requests
- Detect and Get the Client IP Address
- How to Upload Files
- Quick Access to Logged In User in Route Handlers
- How to Fix “handler method did not return a value, a promise, or throw an error”
- How to Fix “X must return an error, a takeover response, or a continue signal”
- Query Parameter Validation With Joi
- Path Parameter Validation With Joi
- Request Payload Validation With Joi
- Validate Query and Path Parameters, Payload and Headers All at Once on Your Routes
- Validate Request Headers With Joi
- Reply Custom View for Failed Validations
- Handle Failed Validations and Show Errors Details at Inputs
- How to Fix AssertionError, Cannot validate HEAD or GET requests
Preparation
Actually, we guess you’ve already created your hapi based project. Nonetheless, to get everyone on the same page let’s shortly recap what this guide is about.
First, create your hapi server instance, define the connection settings and afterwards register your desired plugins. Up to this point, you should be familiar with the code snippet below. If you don’t feel comfortable, just wind back and read the tutorial on how to extend your hapi server using plugins.
const Hapi = require('hapi')
// create new server instance
const server = new Hapi.Server()
async function liftOff() {
server.register([
{
plugin: require('hapi-auth-basic')
},
{
plugin: require('hapi-auth-cookie')
}
])
// TODO: add authentication strategies
// TODO: define default auth strategy
// TODO: add routes
try {
await server.start()
console.log('info', 'Server running at: ' + server.info.uri)
} catch (err) {
console.error(err)
process.exit(1)
}
}
liftOff()
The snippet above outlines the fundamental steps to create your hapi server and register two plugins that can be used to prepare authentication within your app.
Register Authentication Strategies
You’re not right at the point of defining multiple authentication strategies for a route, because the server setup isn’t complete to actually use the registered auth plugins. You need to create authentication strategies based on the newly available authentication schemes. You can find more information about the individual authentication types within the detailed tutorials on basic authentication with hapi and session based authentication using cookies in hapi.
// register your auth strategies
server.auth.strategy('simple', 'basic', { validateFunc: basicValidationFn })
server.auth.strategy('session', 'cookie', { password: '…' })
Once you have more than a single authentication strategies available, you need to define a default one. Last week’s guide walks you through two different types on how to set a default authentication strategy. For now, you can go ahead and set a default strategy using the following line of code:
// default auth strategy avoids server crash for routes without auth config
server.auth.default('simple')
Basically, you only need to define a default authentication strategy if you’ve created multiple authentication strategies and also have routes available that don’t specify an auth
configuration. In those cases, hapi will throw an error to indicate this issue right at server start. Even though that’s annoying, there’s no rude surprise during runtime.
Configure Multiple Strategies for a Route
Finally, you’re at the point of defining multiple authentication strategies for your routes. You’re using the same auth
config object as you would do within your previous authentication setup. The thing that changed is the field you’re going to set, namely strategies
with an array of authentication strategy names.
server.route({
method: 'GET',
path: '/profile',
config: {
auth: {
strategies: ['simple', 'session']
},
handler: (request, h) => {
return h.view('profile')
}
}
})
Within the preparation part of this tutorial, you’ve created two authentication strategies: simple
and session
. Within the route configuration above, you’re allowing both strategies to access the /profile
path.
That’s the trick to allow multiple authentication strategies for your routes!
When to Use Multiple Authentication Strategies for a Route?
Actually, there are various use cases and scenarios to apply more than just a single strategy. For example, we at Future Studio use multiple auth strategies for the endpoint to create short-links from tutorial urls. Precisely, anyone within the team can create a short-link from an access restricted web view and also via an API call (using Postman or any other client) that requires authentication via a JWT token.
Outlook
Allowing multiple authentication strategies is beneficial in various scenarios. This guide shows you the details that are required to define multiple, different authentication strategies for your routes.
We appreciate feedback and love to help you if there’s a question in your mind. Let us know in the comments or on twitter @futurestud_io.
Make it rock & enjoy coding!
Additional Resource
- Add basic authentication to your hapi app
- Add authentication and remember me using cookies with hapi
- Set a default authentication strategy in hapi
- how to extend your hapi server using plugins