Before the server starts, all plugins etc are registered. I create my strategy and set JWT as default authentication method for the server.
await server.register(require('hapi-auth-jwt2'));
await server.register(require('~/utils/jwt-key-signer'));
server.auth.strategy(
'jwt', 'jwt',
{ key: process.env.API_KEY,
validate: true, // Temporarily using true
verifyOptions: { algorithms: [ 'HS256' ] }
});
server.auth.default('jwt');
Here's my route. I pass the payload from the handler request into a plugin that signs my key and returns a token:
'use strict';
const Boom = require('boom');
exports.plugin = {
name: 'user-create',
register: (server, options) => {
server.route({
method: 'POST',
path: '/user/create',
options: { auth: 'jwt' },
handler: async (request, h) => {
const { payload } = await request;
const { JWTKeySigner } = await server.plugins;
const token = await JWTKeySigner.signKeyReturnToken(payload);
const cookie_options = {
ttl: 365 * 24 * 60 * 60 * 1000, // expires a year from today
encoding: 'none', // we already used JWT to encode
isSecure: true, // warm & fuzzy feelings
isHttpOnly: true, // prevent client alteration
clearInvalid: false, // remove invalid cookies
strictHeader: true // don't allow violations of RFC 6265
}
return h.response({text: 'You have been authenticated!'}).header("Authorization", token).state("token", token, cookie_options);
},
options: {
description: 'Creates a user with an email and password',
notes: 'Returns created user',
tags: ['api']
}
});
}
};
Here's how I sign my key:
const jwt = require('jsonwebtoken');
exports.plugin = {
name: 'JWTKeySigner',
register: (server, options) => {
server.expose('signKeyReturnToken', async (payload) => {
jwt.sign(payload, process.env.API_KEY, { algorithm: 'HS256' }, async (err, token) => {
if (err) {
console.log(err)
}
await console.log(`TOKEN${token}`);
return token;
});
})
}
};
I then visit my route from Postman, then pass my user which contains an email address and password back to the round as JSON, and this is the response I get:
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Missing authentication"
}
Ok, so that proves my route is successfully being protected. I now proceed to add my token into Postman:

Then I get this error:
{
"statusCode": 500,
"error": "Internal Server Error",
"message": "An internal server error occurred"
}
If I remove the token from postman, I get the "unauthorised" error.
All I'm trying to do is block outside access to my API, and only allow people who have permission to access it. This would be regular users who signup.
When I paste my token into JWT.io, I can see my data on the right hand side of the page, but JWT tells me it's an invalid signature.
I'd really appreciate some clarity here. I'm using hapi-auth-jwt2.
Thanks in advance
Hmm, I was writing another message to you but then I checked hapi-auth-jwt2 docs for validate options and it says;
validate - (required) the function which is run once the Token has been decoded with signature
async function(decoded, request, h) where:
decoded - (required) is the decoded and verified JWT received in the request
request - (required) is the original request received from the client
h - (required) the response toolkit.
Returns an object { isValid, credentials, response } where:
isValid - true if the JWT was valid, otherwise false.
credentials - (optional) alternative credentials to be set instead of decoded.
response - (optional) If provided will be used immediately as a takeover response.
Just try
server.auth.strategy(
'jwt', 'jwt',
{ key: process.env.API_KEY,
validate: validate: () => ({isValid: true}), // Temporarily using true
verifyOptions: { algorithms: [ 'HS256' ] }
});
Then let's see if 500 error continues.
Maybe some other thing in your code that throws an error. Did you enable debug on your server setup? You should see the details of that 500 error in your server console.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With