ryanfitz / hapi-auth-jwt Goto Github PK
View Code? Open in Web Editor NEWJSON Web Token (JWT) authentication plugin
License: Other
JSON Web Token (JWT) authentication plugin
License: Other
Hello,
I've upgraded an old Nodejs project to the latest Hapi version... I've read your documentation but I got this error when I start the Nodejs application...
Here's my code
const init = async () => {
const server = Hapi.server({
port: port,
host: 'localhost',
routes: { cors: { credentials: true } }
});
// include our module here ↓↓, for example, require('hapi-auth-jwt2')
await server.register(require('hapi-auth-jwt2'));
server.auth.strategy('jwt', 'jwt',
{
key: 'SECRETKEYIHAVE',
validateFunc: Auth.login_validate,
verifyOptions: { algorithms: ['HS256'] }// validate function defined above
});
server.auth.default('jwt');
server.route(routes);
await server.start();
logger.info('Server running on %s', server.info.uri);
return server;
};
process.on('unhandledRejection', (err) => {
logger.error(err.message);
process.exit(1);
});
init();
and here's my package.json
{
"name": "aaa-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"boom": "^4.2.0",
"dotenv": "^8.2.0",
"@hapi/hapi": "^20.0.1",
"hapi-auth-jwt2": "^10.0.2",
"joi": "^10.2.0",
"minimist": "^1.2.0",
"mssql": "^3.3.0",
"request": "^2.81.0",
"tedious": "^1.14.0",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^4.5.0",
"xmlbuilder": "^8.2.2",
"uuid": "^8.3.1",
"seq-logging": "^0.4.6"
}
}
Any suggestion?
Thanks in advance
The validate callback signature is documented in the README as function(token, callback)
but it should be function(request, token, callback)
. Git blame suggests that it should have been updated here but wasn't: 49a4737
In order to easily support multi tenant scenarios, it would be useful to have optionally have a callback function take the JWT and return the key.
To keep the API simple the idea would be to keep the current behavior if key
is not a function. If key
is a function then this fragment would look like this:
var token = parts[1];
var key = isFunction(settings.key) ? settings.key(token) : settings.key;
jwt.verify(token, key, function(err, decoded) {
What do you think about it?
I'm working on a PR with the updated docs, implementation and tests.
Do you think its cause for concern that the underlying implementation of node-jsonwebtoken is not built in an async manner? I'm not sure if this would impact performance or not, but if there is a high demand for signing and decrypting...
I just wanted to get your thoughts.
With regards,
Patrick
My handler function looks like this. At the beginning of the file..i require'd 'jsonwebtoken'. I am wondering if this approach is correct. Any advice appreciated.
//------begin--------------------
exports.secretPage = {
handler : function(request, reply) {
var privateKey = Config.key.privateKey;
if(hoek.contain(request.headers, 'authorization',{once: true}) === false )
reply(Boom.forbidden("authorization header missing"));
jwt.verify(request.headers.authorization.split(" ")[1], privateKey, function(err, decoded) {
if(decoded === undefined) return reply(Boom.forbidden("invalid Token"));
return reply("Here is your secret page"); //All is well...
});
}
};
//------------END -------------
I need two keys. One for api key (the vendor of the service with the scope) and the authorization key (the user's only).
The use case here is the hapi server is siting behind a gateway that is validating the jwt tokens, so by the time the request makes it to the hapi server we already know the token is valid. But we do want to access the jwt payload to use the information. Would you be open to a PR to allow this?
What I'm thinking is if key
in the options has the value false
the authenticate
function would call jwt.decode
instead of jwt.validate
.
hapi-auth-jwt requires an old version of jsonwebtoken
(5.x), which depends on ms
which has a ReDoS vulnerability. Please update jsonwebtoken
to use at least 7.4.1 which has fixed this issue.
Thanks!
when you install through npm, it installs version 2.1 instead of 4.0. in the new version where validateFunc called, request object also passed, but in 2.1, it only passes token and callback.
how can we put the Token in blacklist so it will be not accessible anymore same like require('express-jwt-blacklist')
Are you planning to update this to work with 6.0?
There is a guide of how to update / what changed: hapijs/hapi#1664
I am trying to write my own unit tests modeled after the tests in the package...
my test script lives in a structure like this//
app_root
---- node_modules
---- server /
--- test/server/api/users.js ( this is my test script)
when i run npm test...i get the following error..."Cannot read property 'register' of undefined"...
Inside the test script in modules i see this line 'server.register(require('../'), function (err) {'
what should i change it to in my script so that it runs?? sorry this is more of a 'how do in..hapi js' query than a question specific to hapi-auth-jwt..
any pointers appreciated...
I don't know is there any way of deactivate a jwt token when user loggedout.
since 2 months I did not get any possible way of doing it.
Can anyone help me ?
My server configuration are below:-
const validate = async function (user,decoded, request) {
// checks to see if the person is valid
if (!user["_id"]) {
return { isValid: false };
}
else {
return { isValid: true };
}
};
await server.register(require('hapi-auth-jwt2'));
server.auth.strategy('jwt', 'jwt',
{ key: process.env.SECRET_KEY,
validate:validate,
verifyOptions: { algorithms: [ 'HS256' ] }
});
`
At the time of login I am issuing jwt token from
const token = JWT.sign(user.toJSON(), process.env.SECRET_KEY);
Now I want to destroy that issued token
I am using hapi 17 with hapi-auth-jwt2 package
Please give me solution with code so that I can implement it .
{
"statusCode": 400,
"error": "Bad Request",
"message": "Bad HTTP authentication header format"
}
kindly help me to resolve it i am new to hapi
Hi, maybe it’s me, but I cannot make the example work. What is the purpose of this line? What should I put instead of the require('../index’) ?
server.register(require('../index'), function (error) {...
Thx!
I have successfully created a token, and I'm wondering how do I pass this thing to my client (CORS)?
I was wondering if there was a way to destroy/delete/deactivate/whatever a JWT thats been validated and currently in use.
Im moving my application over from CodeIgniter, which allows you to keep the sessions in a database, which makes it easy to terminate account sessions if needed. I was trying to get the same effect here, by destroying the users JWT token
I get the error Hapi 6.x has deprecated pack.require() using the sample code on the readme
However when i switch it to the pack.register syntax I get
throw new Error(msgs.join(' ') || 'Unknown error');
^
Error: Missing plugin name
Hi
I'm a newbie so forgive me if this is a naive question.
I'm adding (JWT based) authentication (https://github.com/ryanfitz/hapi-auth-jwt) to my Hapi service. I think I've set it up correctly except one thing. My validate function looks like this:
`
const validate = function (request, decodedToken, callback) {
const originalToken = request.headers.authorization.split(' ')[1]
//return callback(null, true, {'id': decodedToken, 'name': 'vijay'});
globalTokenCache.get(originalToken, function (err, value, cached, log) {
if (err) {
return callback(err, false, value);
}
if (!value) {
return callback(err, false, value);
}
if (decodedToken !== value['id']) {
return callback(err, false, value);
}
return callback(err, true, value);
});
};
`
Validate function fails and I get a not authenticated error when in reality everything is alright.
I figured that this happens because the validate function returns before the cache.get callback is fired. If I (uncomment and ) return from the second line of the callback itself, authentication succeeds.
I know there isn't a synchronous version of server.cache.get but is there a workaround that I can employ when the user lookup happens inside of a callback?
I feel I'm doing something wrong for me to be stuck here - I don't see others complaining about this.
I am trying the plugin out and want to make sure expiresIn
options works.
When I create a token:
var token = jwt.sign({accountId: 123}, privateKey, {expiresIn: '0'});
or
var token = jwt.sign({accountId: 123}, privateKey, {expiresIn: '-1'});
Then just run the code from the example, it doesn't show it as a wrong token, sends all the restricted data.
Am I doing something wrong?
Should only required removing tos
support hapijs/hapi#1960
What if I need to perform additional checks against raw token during validate? At the moment we have only decodedToken, but if I need to check if that key exists in the Redis ( "blacklist" ) I can't do that because I don't have raw token..
Hi,
sorry to bother you.
What's the purpose of var error in validate function
because afaik is always undefined.
var validate = function (decodedToken, callback) {
var error,
credentials = accounts[decodedToken.accountId] || {};
if (!credentials) {
return callback(error, false, credentials);
}
return callback(error, true, credentials)
};
Thanks in advance.
The current implementation has a security vulnerability: the attacker can use the 'none' algorithm and fake a token since the list of allowed algorithms is not specified (reference article).
The library used internally (jsonwebtoken) allows specifying the latter as an optional 3rd parameter, check jwt.verify.
So this is just a matter of exposing the functionality in the plugin's configuration.
Below is the verifyOptions
I am using to verify the token sent
verifyOptions: { algorithms: ['HS256'], maxAge: 60 }
When using the below token payload, it does not throw the "TokenExpiredError"
{ iss: 'Online JWT Builder', iat: 1542859570, exp: 1574395630, aud: 'www.example.com',.....}
@ryanfitz Could you help me fix this?
In package.json, at least.
When i require (jsonwebtoken). ..this is thrown Error: Cannot find module 'jsonwebtoken'.
I have hapi-auth-jwt installed....this is an excertp of my package.json
"dependencies": {
"bcrypt": "^0.8.3",
"boom": "^2.7.2",
"hapi": "^8.6.1",
"hapi-auth-basic": "^2.0.0",
"hapi-auth-jwt": "^2.1.2",
"hapi-auth-jwt2": "^4.4.0",
"joi": "^6.4.3",
"json-web-token": "^1.5.3",
"mongoose": "~3.8",
"mrhorse": "^1.1.0"
}
This is the output of npm version....
{ behapi: '1.0.0',
npm: '2.7.4',
http_parser: '2.3',
modules: '14',
node: '0.12.2',
openssl: '1.0.1m',
uv: '1.4.2-node1',
v8: '3.28.73',
zlib: '1.2.8' }
I added jwt=require('jsonwebtoken') at the top of server.js..this is my main js file.
What am i doing wrong. This is what i am trying to accomplish.
UPDATE:
It worked. Apparently i had the wrong jsonwebtoken module. I removed json-web-token and added jsonwebtoken and all is well.
Based on the sample code I would be using jsonwebtoken - however I do not see any mention of scope on that module. Your sample code shows scope use. How would I get that to work?
The docs state that validateFunc is a function with the following signature
function (request, decodedToken, callback)
As of now, the signature is actually
function(decodedToken, callback)
Consider making changes in either the documentation to reflect this or making changes in validateFunc
code.
i've installed the module but can't seem to get the validation function to run, does it have to be called explicitly? or the validateFunc option will run automatically as long as there is a function supplied?
I am trying to parse the token ias to expire it after a certain time period.
Thanks :)
Would it not be better if the validate function has access to the request object so that other plugins can be accessed and used for validation for. e.g. checking redis for token and fetching cached info?
Hey @ryanfitz - mind if I took over this module on npm?
You can reach me at [email protected].
Thanks!
Apologies if this is mentioned elsewhere. The private key used for signing the tokens, is this the same as a private key generated using ssh-keygen?
I was able to get hapi-auth-jwt working just fine using the example JS code in the readme, but I would like to have the hapi-auth-jwt plugin written as an external HapiJS module.
Reading the Creating A Plugin tutorial on the Hapi website shows how to register a plugin, and how to do the same thing as an external module, which I've been able to do with everything else I have used thus far.
It shows you setup the module registration as the exports.register
value:
exports.register = function (server, options, next) { /* Plugin stuff */ }
But in your readme example, its quite different
server.register(require('hapi-auth-jwt'), function (error) {
I understand how to work exports in NodeJS, im just not sure how I should structure the register
export for this case
I'm sure this is something simple, I'm just new to HapiJS, but if you can provide an example of using this module as an external plugin, that would be very helpful.
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.