During the last two weeks, you’ve learned how to add the functionality of basic authentication with username and password to your hapi server and also remember your users with the help of cookies once they authenticated successfully so that they don’t need to provide their credentials on every visit.
Hapi handles both authentication methods as individual strategies and you can specify each one for routes to be applied. This guide will show you how to define a default authentication strategy in case you’ve multiple registered.
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
At first, you have to prepare your hapi server. Let’s set up a basic hapi server that listens on localhost:3000
for incoming requests. Further, you’ll register the hapi-basic-auth
plugin as an authentication strategy. This tutorial aims to provide you the fundamentals on how to set a default authentication strategy and it’s sufficient to just use a single one. No need to bloat this guide with irrelevant information.
const Hapi = require('hapi')
// create new server instance
const server = new Hapi.Server()
async function liftOff() {
server.register({
plugin: require('hapi-auth-basic')
})
// TODO: add authentication strategy
// 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()
As you can see, the hapi-auth-basic
plugin is registered to your server
instance and if everything went fine, the server can be kicked off its socks to wait for connections (even though there’s no route available). Having the plugin registered successfully, you can go ahead and add the required authentication strategy.
Unfamiliar With Authentication in Hapi?
If you’re unfamiliar with the term “strategy” in the context of hapi authentication, please visit any of the mentioned guides related to basic and cookie based authentication. There, you’ll find the fundamentals required to get an overview on how hapi supports authentication to applications.
Register Authentication Strategy and Set as Default
The following code snippet illustrates the registration of a new default authentication strategy based on the previously registered basic
auth plugin. Actually, the most import part is the third parameter within the server.auth.strategy(args)
call. The third parameter is optional and depicts the strategy’s mode
. It indicates whether the new strategy is default (true
or 'required'
) or not (false
, 'try'
, 'optional'
, just skip the parameter).
// Create auth strategy and set it as default
// all routes will automatically require and follow the default strategy
server.auth.strategy('simple', 'basic', true, { validateFunc: basicValidationFn })
We’ll get into the details of strategy modes within a later tutorial. For now it’s important to know that you can set a default auth strategy at the same time of creating it.
Set Default Strategy Separately From Registration
Adding an authentication strategy doesn’t force you to decide and set it default or not. You can just leave the parameter empty to indicate it’s not the default strategy.
// Create auth strategy, without setting it as default
server.auth.strategy('simple', 'basic', { validateFunc: basicValidation })
This way, you can register different authentication strategies and afterwards choose and set the default one. To define a default strategy, use server.auth.default('strategy-name')
or create an authentication object like you would do on your route configuration. Let’s have a look at both options in the sections below.
Set Default by Strategy Name
You can set a default strategy straight forward by leveraging hapi’s server.auth.default('name')
functionality. You need to provide a strategy name that’s actually registered to your server instance and available to be applied for the routes that will be added afterwards.
// set default auth strategy separately
// all routes added afterwards will follow the default, required auth strategy
server.auth.default('simple')
Notice: setting a default authentication strategy requires you to previously create it with server.auth.strategy('simple', …)
.
Set Default by Object
Hapi provides a second way to configure a default authentication strategy, namely an object as you would provide for the auth
configuration on a route. You’ve the options mode
, strategy
and payload
(which explicitly defines payload authentication and requires a strategy with support for payload authentication, like Hawk).
The following code block outlines the config object to set simple
as the default strategy.
var config = {
mode: true,
strategy: 'simple',
payload: false
}
server.auth.default(config)
What if I Set Two Default Strategies?
In short: hapi replaces the previously defined default strategy. If you didn’t have a default strategy defined before, it will become the default one.
server.auth.default('simple')
server.auth.default('cookie')
In this example, the authentication strategy called cookie
becomes the default one.
If you provide a strategy name that isn’t available and wasn’t created before, hapi will throw an error during server start.
What if My Routes Don’t Use the Default Strategy?
Actually, there’s a little detail you need to know about default strategies: if you set them via server.auth.default('name')
, hapi will apply it only to routes added afterwards and those routes that don’t have an authentication configuration available.
In case you define a strategy as default at the same time of creating it (server.auth.strategy('name', 'scheme', true, options)
), hapi applies it to every route already registered and those that will be added afterwards.
Outlook
This guide walked you through the configuration of a default authentication strategy on your hapi server. Further, you’ve learned both ways of defining a default strategy: by name and configuration object. Please keep in mind that not all routes may use your default strategy, depending on the way and moment you’re setting the default auth.
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 Resources
- Use basic authentication with username and password in hapi
- Authenticaiton in hapi and remember me using cookies
- hapi-auth-hawk plugin that provides Hawk authentication for your hapi app