koajs / jwt Goto Github PK
View Code? Open in Web Editor NEWKoa middleware for validating JSON Web Tokens
License: MIT License
Koa middleware for validating JSON Web Tokens
License: MIT License
Current dep is on ~0.4.x
, latest version is 1.1.2
Noticed that audience arrays weren't working with koa-jwt for example
We pass a function to secret
so that it can verify the JWT based on the kid
in the header. The kid
is something like <issuer>/<key-id>
. We would also like to verify that the issuer
in the token is correct to avoid that a compromised private key is used to impersonate another service e.g. doing something like token.header.kid.startsWith(token.payload.iss + '/')
. Unfortunately we cannot do that ourselves at the moment as only the payload is returned by jsonwebtoken.verify which is used by this lib, and only the header is passed to the secret provider.
I'm proposing that the provider is called with both the header and the payload as a second argument to avoid a breaking change. If you're OK with that, I'm happy to send a PR for that.
Are there plans for supporting koa@2?
Update the middleware to koa2.
I get sign is not defined
error when doing (v2)
npm install koa-jwt@v2
const jwt = require('koa-jwt');
jwt.sign({ role: 'user' }, 'A very secret key')
After using this by wrapping it in koa-convert, my koa app throws an error Can't remove headers after they are sent
. Any idea?
Is this module actively maintained?
Type definitions in types/index.d.ts don't support the documented configuration using jwks. Typical configuration looks like this:
import * as jwt from 'koa-jwt'
import * as jwks from 'jwks-rsa'
export default jwt({
secret: jwks({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: "https://foo.com/.well-known/jwks.json"
}),
audience: 'https://foo/',
issuer: "https://foo.com/",
algorithms: ['RS256']
})
And this code works in js. It's easy enough to have a workaround with the missing audience issuer and algorithms keys but the secret is defined as sting | Buffer
I'll happily submit a PR for the missing keys; but I'm not quite sure what to do with the secret.
I'm trying to implement this with koa-router and I can't seem to get it work, I'm somewhat new to koa so I'm sure I'm just misunderstanding something in the koa architecture, but is there a way to get these two modules to play nice?
The docs say state.user gets "set". But what does it get set to? I expected that this module saves the payload of the JWT in state.token or something like that.
I've just been reading Koa's v2 roadmap, and spotted this:
All of the current stable versions of middleware should be targeting koa v1. If it doesn't, let us know and we'll fix it.
Middleware may have an "alpha" version of the koa v2 version. These should NOT be marked as stable. If they do not exist, let us know and we'll create an alpha version so you can try it with koa v2. Better yet, make a PR!
Unfortunately my recent npm publish of v2 had dist-tag latest
, so if someone starts a new empty project and runs npm install koa koa-jwt
, they will end up with koa v1.2.4 and koa-jwt v2.2.1 ๐ข Consider this minimal example script in that environment:
const koa = require('koa');
const jwt = require('koa-jwt');
const app = koa();
app.use(jwt({ secret: 'shhh' }));
app.listen(3000);
This dies with AssertionError: app.use() requires a generator function
. Sorry if anyone has been affected, it's my fault. I'll republish the 1.x branch ASAP with the latest
tag to correct this.
For the v2 branch we should probably do what Koa does. This means that an npm publish
on v2 will have the right tag automatically.
v2 should be the latest on NPM now that Koa v2 is the latest.
Validating claims within audience and issuer fields never fail.
Validating
app.use(jwt( { secret: 'shared-secret', audience: 'http://myapi/protected', issuer: 'http://issuer' }));
against a token containing
{ ... audience: 'something-nice', issuer: 'bogus' ... }
does not fail.
Does this seem sensible?
The typings for Options indicate that getToken's first parameter should be the options for the middleware. The documentation says that getToken's first parameter should be the options for the middleware and that "this" inside the function should be the Koa context.
In the code itself, the first parameter to getOptions is (very sensibly) the Koa context, while the options are the second parameter.
To get around this, I used a hack like this:
// "get" below is lodash's get method.
const koaJwtOptions = {
secret: config.secret,
getToken(opts: any) { // opts is ACTUALLY Koa.Context
const jwt = get(opts, "query._j") || get(opts, "query.jwt")
return jwt;
}
}
It would be nice to allow passing the token on the query string (?token=....
) instead of having to passing it as a request header. express-jwt permits this by allowing you to pass a custom getToken function like so:
app.use(jwt({
secret: 'hello world !',
credentialsRequired: false,
getToken: function fromHeaderOrQuerystring (req) {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
return req.headers.authorization.split(' ')[1];
} else if (req.query && req.query.token) {
return req.query.token;
}
return null;
}
}));
Why is sign function missing in 2.1.0? Will it be added in the future? For now should i use one from jsonwebtoken ?
there is my question:
I want to user koa-jwt
to help me to build the verification system with [email protected], so I am installed link this:
npm install koa-jwt --save
And I run the example like readme, but it doesn't work. I get confused. Later, I realize that is the compatibility between [email protected] and [email protected].
npm install koa-jwt@1 --save
It worked! :)
So, I thought write the installation information in the readme will be good.
error when use node --debug bin/run to debug on VSC
try node version 7.0-7.9 all failed
`
Debugging with legacy protocol because a runtime executable is set.
npm run-script start
[email protected] start /Users/xxx/Desktop/pro
nodemon --debug bin/run
[nodemon] 1.11.0
[nodemon] to restart at any time, enterrs
[nodemon] watching: .
[nodemon] startingnode --debug bin/run
Debugger listening on 127.0.0.1:5858
/Users/xxx/Desktop/pro/node_modules/koa-jwt/lib/index.js:17
const middleware = async function jwt(ctx, next) {
^^^^^^^^
SyntaxError: Unexpected token function
at Object.exports.runInThisContext (vm.js:78:16)
at Module._compile (module.js:543:28)
at Module._extensions..js (module.js:580:10)
at Object.require.extensions.(anonymous function) [as .js] (/Users/xxx/Desktop/pro/node_modules/babel-register/lib/node.js:152:7)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object. (/Users/nathanmb/Desktop/luim/app.js:16:13)
at Module._compile (module.js:571:32)
at loader (/Users/xxx/Desktop/pro/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (/Users/xxx/Desktop/pro/node_modules/babel-register/lib/node.js:154:7)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
[nodemon] app crashed - waiting for file changes before starting...
`
I'm using koa-jwt for koa@2, so I installed koa-jwt by running npm i --save koa-jwt@koa2
.
Authorizing token works, but when I call ctx.state.user
, it returns undefined
. I did some debugging and it turns out that this line is executed after route handler function is called. Any idea how to fix this?
Some very useful debugging information is available when JWT authentication fails. However, if passthrough
is being used, this information is made unavailable. As a result, it cannot even be logged.
I'd love to see that info be made available somehow.
Is this getting updated soon? getting npm deprecated warning
npm WARN deprecated [email protected]: Critical vulnerability fix in v5.0.0. See https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
Switching to ctx.state.user
in a minor version update breaks all of existing code that depends on 0.x branch! It's highly inconvenient and minor version change should be reverted to working state while the changes should be applied to 1.x branch. Koa will probably follow the same pattern as they are holding back a new release for some time.
Is it normal that the JWT.verify function is called without the callback function parameter?
yield JWT.verify(token, secret, opts)
Yet, in jsonwebtoken module, it is :
JWT.verify = function(jwtString, secretOrPublicKey, options, callback)
jsonwebtoken module tests if the third parameter is a function or not, and if so, take the third parameter as the callback function but what if I want both opts and callback?
I realize this is very nit-picky.
Commit 9cf6a15 adds a tokenKey that writes the raw token to the key specified. This'll break backwards compatibility if the "key" preference is set to 'token' like this:
const jwt = require('koa-jwt');
jwt({ key: 'token'});
In that case, the value at token will be the user variable in versions <=1.2.0 but the raw string token in 1.3.0 >=.
The types
directory hasn't been published to npm. So after npm install [email protected] --save
, there are no types on node_modules/koa-jwt.
app.use(jwt({secret: function *(next) {
this.state.secret = getFromDB(this.headers.XXXX)
yield next;
}}))
Would love to use this library, but my organization will not allow it because it fails the NSP check.
nsp check --reporter checkstyle
Prototype pollution attack
Name: hoek
CVSS: 4 (Medium)
Installed: 2.16.3
Vulnerable: <= 4.2.0 || >= 5.0.0 < 5.0.3
Patched: > 4.2.0 < 5.0.0 || >= 5.0.3
Path: XXXXXXXXXX > > [email protected] > [email protected] > [email protected] > [email protected]
More Info: https://nodesecurity.io/advisories/566
Looks like upgrading jsonwebtoken to 8+ should resolve this: https://github.com/auth0/node-jsonwebtoken/wiki/Migration-Notes:-v7-to-v8
Once I have verified the jwt, I want to check if a certain field is set properly.
For eg:
If I have set a role
field in jwt, on admin routes I want to only allow to pass if the role is set to admin
.
role => jwt({
secret: confirm.secret,
validate: decoded => decoded.role === role
})
I always thought that if my token isn't valid I can't get next middleware. Is it correct logic?!
But I'm using your middleware and it isn't working how I thought.
return JWT.verifyAsync(token, secret, opts)
.then(isRevoked(ctx, token))
.then(user => {
ctx.state = ctx.state || {};
ctx.state[opts.key] = user;
if (opts.tokenKey) {
ctx.state[opts.tokenKey] = token;
}
})
.catch(e => {
if (!opts.passthrough) {
const msg = 'Invalid token' + (opts.debug ? ' - ' + e.message : '') + '\n';
ctx.throw(401, msg);
}
})
.then(next);
petkaantonov/bluebird#476
Do you know about it?
under some special circumstances, function jwt
can work but tokenResolvers.find
can't work, so token is undefind
, it happend after I download a file form server, when I use
tokenResolvers.forEach(resolver => {
if (resolver(ctx, opts)) {
token = resolver(ctx, opts);
}
});
instead of
tokenResolvers.find(resolver => token = resolver(ctx, opts));
it can works well after I download file
not just verify
Hi I'm getting the following warning
koa deprecated Support for generators will be removed in v3. See the documentation for examples of how to convert old middleware https://github.com/koajs/koa/blob/master/docs/migration.md server/index.js:42:5
my example code:
...
app.use(jwt({ secret: Token.secret }).unless({ path: [
/^\/api\/authentication/,
/^\/api\/signup.*/,
]}));
...
I whish to know howto remove the warning, Docs says that I should to use async
/await
version of the middleware, however I didn't found howto make that in the Readme.
Any help will be appreciated.
Best Regards.
export interface Options {
secret: string | Buffer;
key?: string;
getToken?(opts: jwt.Options): string;
passthrough?: boolean;
cookie?: string;
debug?: boolean;
}
isRevoked ???
Hello,
Correct me if I'm wrong but I think that the Alg field is not an option that can be fixed in this jwt module, alg is known to the server-side and should be checked before analyzing the token !
Auth0 issued a statement saying that not fixing the alg field can introduce a security break :
tl;dr : The fact that the header is not crypted and checked means that anyone can simply fix the alg field he wants : none, SHA512, SHA256 etc. a public key can become a private key etc.
jsonwebtoken, the library powering koa jwt offers this feature, should be simple to make a fix :). Waiting for your inputs before doing any fix.
In the interface comment:
If the token is not revoked, the promise must resolve with false, otherwise (the promise resolve with false or error) the token is revoked
should be
If the token is not revoked, the promise must resolve with false, otherwise (the promise resolve with true or error) the token is revoked
It will be misleading
The version this module uses is 5.0.5, while the newest is 5.4.0. There is no reason why this module uses a tilde ~ dependency on jsonwebtoken and not a caret ^ dependency. The exported sign/verify functions miss features the newest jsonwebtoken version has. I have to use option expiresInSeconds which is already deprecated in the newest version.
Will this module be supporting async/await with koa@next
?
There seem to be significant changes to jsonwebtoken.
I'm using: "koa": "^2.0.0-alpha.3", and "koa-jwt": "^2.0.1" like so:
router.post('/api/userupdate', jwt({secret: config.database.jwtSecret}),
function* (next){
this.body = this.request.body
console.log(this.body)
yield this.body
}
)
app.use(router.routes()).use(router.allowedMethods())
But I'm getting the not auth error message in subject. The jwt token is send with the request headers on the 'Authorization' . What's wrong with my implementation?
const middleware = async function jwt(ctx, next) {
The code above throws a SyntaxError: Unexpected token function, why?
This project is now two major versions behind current jsonwebtoken (7.1.6 at the moment). Any plans on catching up?
The current implementation allow me to pass different secret to verify the token using ctx.state.secret
its also possible to get a function to make it done.
In current implementation of secret function is called like that return provider(decoded.header);
I want to be able decide on my secret based on payload
Proposed Solution:
return provider(decoded.header, decoded.payload);
it's will not affect the current existing code and look like safe to add it
update
actually have pending pull request to https://github.com/koajs/jwt/pulls
Hi, is possible to wrap this middleware or any way to add dynamic aud?
pseudocode example:
const checkJWT = async (ctx, next) => {
return await koajwt({secret: 'secret-string', audience : ctx.get('x-custom-header')});
}
app.use(checkJWT());
thanks in advance.
Suggestion for using node-jsonwebtoken module error message
see https://github.com/auth0/node-jsonwebtoken errors:
TokenExpiredError and JsonWebTokenError
change file index.js line 51
if (!passthrough) {
const msg = debug ? e.message : 'Authentication Error';
ctx.throw(401, msg);
}
change to
if (!passthrough) {
const msg = debug ? e.message : e.message || 'Authentication Error';
ctx.throw(401, msg {name : e.name || 'UnauthorizedError'});
}
Hi! I installed koa-jwt via npm, and was running into issues trying to use the changes outlined in this PR: #39
I noticed it was included in the 1.2.0 tag here on github, but the latest install (1.2.0) from npm has an older version which does not include these changes.
I see it was stated NPM was updated (#39 (comment)), but it doesn't seem to be that way heh :)
I understand we can add a debug flag now to the options like this as suggested in #98 but it seems like it would be better to have access to the original error object.
Line 53 in 950094a
originalError
instead and assign it the original error from jsonwebtoken (e.g. TokenExpiredError).ctx.throw(401, msg, {originalError: e});
Where originalError.message would be something like "jwt expired" that end clients could key on to know to refresh the token.
Then we could do something like this to notify client apps about the problems that they might need to handle (e.g. token expiration).
// Custom 401 handling
app.use(function (ctx, next) {
return next().catch((err) => {
if (err.status === 401) {
ctx.status = 401;
ctx.body = {
error: err.originalError ? err.originalError.message : err.message;
};
} else {
throw err;
}
});
});
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.