Security News
The Push to Ban Ransom Payments Is Gaining Momentum
Ransomware costs victims an estimated $30 billion per year and has gotten so out of control that global support for banning payments is gaining momentum.
koa-jwt
Advanced tools
Readme
This module lets you authenticate HTTP requests using JSON Web Tokens in your Koa (node.js) applications.
See this article for a good introduction.
koa
version 2+, and you have a version of node < 7.6, install koa-jwt@2
.koa-jwt
version 3+ on the master branch uses async
/ await
and hence requires node >= 7.6.koa
version 1, you need to install koa-jwt@1
from npm. This is the code on the koa-v1 branch.npm install koa-jwt
The JWT authentication middleware authenticates callers using a JWT
token. If the token is valid, ctx.state.user
(by default) will be set
with the JSON object decoded to be used by later middleware for
authorization and access control.
The token is normally provided in a HTTP header (Authorization
), but it
can also be provided in a cookie by setting the opts.cookie
option
to the name of the cookie that contains the token. Custom token retrieval
can also be done through the opts.getToken
option. The provided function
should match the following interface:
/**
* Your custom token resolver
* @this The ctx object passed to the middleware
*
* @param {object} opts The middleware's options
* @return {String|null} The resolved token or null if not found
*/
The resolution order for the token is the following. The first non-empty token resolved will be the one that is verified.
opts.getToken
functionopts.cookie
is set)Normally you provide a single shared secret in opts.secret
, but another
alternative is to have an earlier middleware set ctx.state.secret
,
typically per request. If this property exists, it will be used instead
of the one in opts.secret
.
You can provide a async function to jwt for it check the token is revoked.
Only you set the function in opts.isRevoked
. The provided function should
match the following interface:
/**
* Your custom isRevoked resolver
*
* @param {object} ctx The ctx object passed to the middleware
* @param {object} decodedToken Content of the token
* @param {object} token token The token
* @return {Promise} If the token is not revoked, the promise must resolve with false, otherwise (the promise resolve with true or error) the token is revoked
*/
var Koa = require('koa');
var jwt = require('koa-jwt');
var app = new Koa();
// Custom 401 handling if you don't want to expose koa-jwt errors to users
app.use(function(ctx, next){
return next().catch((err) => {
if (401 == err.status) {
ctx.status = 401;
ctx.body = 'Protected resource, use Authorization header to get access\n';
} else {
throw err;
}
});
});
// Unprotected middleware
app.use(function(ctx, next){
if (ctx.url.match(/^\/public/)) {
ctx.body = 'unprotected\n';
} else {
return next();
}
});
// Middleware below this line is only reached if JWT token is valid
app.use(jwt({ secret: 'shared-secret' }));
// Protected middleware
app.use(function(ctx){
if (ctx.url.match(/^\/api/)) {
ctx.body = 'protected\n';
}
});
app.listen(3000);
Alternatively you can conditionally run the jwt
middleware under certain conditions:
var koa = require('koa');
var jwt = require('koa-jwt');
var app = new Koa();
// Middleware below this line is only reached if JWT token is valid
// unless the URL starts with '/public'
app.use(jwt({ secret: 'shared-secret' }).unless({ path: [/^\/public/] }));
// Unprotected middleware
app.use(function(ctx, next){
if (ctx.url.match(/^\/public/)) {
ctx.body = 'unprotected\n';
} else {
return next();
}
});
// Protected middleware
app.use(function(ctx){
if (ctx.url.match(/^\/api/)) {
ctx.body = 'protected\n';
}
});
app.listen(3000);
For more information on unless
exceptions, check koa-unless.
You can also add the passthrough
option to always yield next,
even if no valid Authorization header was found:
app.use(jwt({ secret: 'shared-secret', passthrough: true }));
This lets downstream middleware make decisions based on whether ctx.state.user
is set.
If you prefer to use another ctx key for the decoded data, just pass in key
, like so:
app.use(jwt({ secret: 'shared-secret', key: 'jwtdata' }));
This makes the decoded data available as ctx.state.jwtdata
.
You can specify audience and/or issuer as well:
app.use(jwt({ secret: 'shared-secret',
audience: 'http://myapi/protected',
issuer: 'http://issuer' }));
If the JWT has an expiration (exp
), it will be checked.
All error codes for token verification can be found at: https://github.com/auth0/node-jsonwebtoken#errors--codes.
Notifying a client of error codes (e.g token expiration) can be achieved by sending the err.originalError.message
error code to the client.
// Custom 401 handling (first middleware)
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;
}
});
});
If the tokenKey
option is present, and a valid token is found, the original raw token
is made available to subsequent middleware as ctx.state[opts.tokenKey]
.
This module also support tokens signed with public/private key pairs. Instead of a secret, you can specify a Buffer with the public key:
var publicKey = fs.readFileSync('/path/to/public.pub');
app.use(jwt({ secret: publicKey }));
If the secret
option is a function, this function is called for each JWT received in
order to determine which secret is used to verify the JWT.
The signature of this function should be (header) => [Promise(secret)]
, where
header
is token header. For instance to support JWKS token header should contain
alg
and kid
: algorithm and key id fields respectively.
This option can be used to support JWKS (JSON Web Key Set) providers by using node-jwks-rsa. For example:
const { koaJwtSecret } = require('jwks-rsa');
app.use(jwt({ secret: koaJwtSecret({
jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json',
cache: true,
cacheMaxEntries: 5,
cacheMaxAge: ms('10h') }),
audience: 'http://myapi/protected',
issuer: 'http://issuer' }));
Note that koa-jwt no longer exports the sign
, verify
and decode
functions from jsonwebtoken
in the koa-v2 branch.
npm install
npm test
Stian Grytøyr
This code is largely based on express-jwt.
FAQs
Koa middleware for validating JSON Web Tokens
We found that koa-jwt demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Ransomware costs victims an estimated $30 billion per year and has gotten so out of control that global support for banning payments is gaining momentum.
Application Security
New SEC disclosure rules aim to enforce timely cyber incident reporting, but fear of job loss and inadequate resources lead to significant underreporting.
Security News
The Python Software Foundation has secured a 5-year sponsorship from Fastly that supports PSF's activities and events, most notably the security and reliability of the Python Package Index (PyPI).