JSON Web Token authentication middleware for Express.js
Under the hood, jwt-identity makes use of jsonwebtoken package for generating and verifying tokens.
Important Notes:
-
Jwt-identity must be mounted after a request body parser so that when jwt-identity needs the content of the request body, it is parsed and available as
req.body
object. -
Jwt-identity automatically provides for refresh token sliding expiration. While a user is being logged in with the use of a valid refresh token, if the refresh token expiration period has less than 25% time remaining, a new refresh token will be issued.
-
Jwt-identity enforces use of the algorithm, provided with configuration options, at token verification. For more information, refer to Critical vulnerabilities in JSON Web Token libraries.
$ npm install jwt-identity --save
const app = require('express')();
const bodyParser = require('body-parser-of-your-choice');
const jwtIdentity = require('jwt-identity');
const options = {
credentials: {
login: 'user_name',
password: 'psw',
rememberMe: 'remember_me',
refreshToken: 'refresh_token'
},
security: {
key: 'secret',
algorithm: 'HS256'
},
grantToken: {
expiresIn: 15
},
refreshToken: {
expiresIn: 90
},
workers: {
getUser (userCredentials) {...}
}
};
// Mount the middleware
app.use(bodyParser());
app.use(jwtIdentity(options));
// Use on ordinary routes
app.get('/some_path', (req, res, next) => {
const isUserAuthenticated = req.identity.user.isAuthenticated;
const userId = req.identity.user.id;
// etc
});
// Route for getting a user logged in
app.post('/login', (req, res, next) => {
req.identity.logIn()
.then(result => {
if (result.statusCode === 200) {
res.status(result.statusCode).json({
grantToken: result.grantToken,
refreshToken: result.refreshToken
});
} else {
res.status(result.statusCode).end();
}
})
.catch(err => next(err));
});
Optional.
Type: Object
Maps string literals that client applications are expected to use as data keys when sending in user credentials in the request body.
Object properties:
{String} login
;{String} password
;{String} rememberMe
- Key for a flag indicating that the user is willing to receive a refresh token;{String} refreshToken
- Key for a refresh token that the client is sending in to get logged in.
If the credentials
option or any of the properties are omitted or resolve to a falsy value, the following defaults are used:
{
login: 'login',
password: 'password',
rememberMe: 'rememberMe',
refreshToken: 'refreshToken'
}
Type: Object
Options for creating and verifying JSON Web Tokens (both, grant and refresh).
Object properties:
{String} key
- Secret key to sign tokens with;{String} algorithm
- Optional. Algorithm to be used for token signing. Default:HS256
.
Currently, jwt-identity only supports JSON Web Signature algorithms:
Algorithm parameter value | Signature algorithm |
---|---|
HS256 | HMAC using SHA-256 hash algorithm |
HS384 | HMAC using SHA-384 hash algorithm |
HS512 | HMAC using SHA-512 hash algorithm |
Type: Object
Grant token configuration.
Object properties:
{Integer} expiresIn
- Time of grant token validity (in minutes). Defaults to15
.
Type: Object
Refresh token configuration.
Object properties:
{Integer} expiresIn
- Time of refresh token validity (in days). Defaults to90
.
Type: Object
Collection of methods that provide communication with the application user data storage.
Get user data from a data storage.
The function is passed the {Object} userCredentials
parameter that contains user data retrieved from the HTTP request as follows:
{String} id
- User ID;{String} login
- User login;{String} password
- User password.
Either id
or login + password
are passed depending on the source of data (refresh token or credentials provided by the user directly).
The function is supposed to return a Promise/A+ that resolves with null
if no user has been found, or, otherwise, with an object with the following properties:
{String} userId
;{String} roles
- A comma separated list of user roles;{String} securityStamp
- Security stamp to be included in or verified against the refresh token;{Object} claims
- A collection of other claims to be included in the grant token.
Jwt-identity extends the req
object with the identity
property.
Type: Object
Properties:
{String} id
- User ID;{Boolean} isAuthenticated
-true
if the request is authenticated;{String} roles
- A comma separated list of user roles;{Object} claims
- A collection of other user claims derived from the grant token.
Type: Function
Function that is supposed to be used on the log-in/sign-up endpoint.
Parameters:
{Object} [user]
Optional. User data. If provided, the process of logging will use this user data instead of invokingoptions.workers.getUser()
. Bypassing user data retrieval might be useful on user sign-up when you want the new user get logged-in immediately but you have distributed storage system with reads on replicas so that immediate retrieval of user data is not guaranteed. The shape of user object is identical to that expected to be returned byoptions.workers.getUser()
.
Returns: {Promise<Object>}
{Integer} statusCode
HTTP response status code:200
- The user has successfully been logged in, and a grant token (and optionally a refresh token) is issued;401
- The log-in failed;
{String|null} grantToken
- Grant token if the log-in succeeded; otherwisenull
;{String|null} refreshToken
- Refresh token if the log-in succeeded AND either the log-in was initiated by user sending in a valid refresh token that needed sliding prolongation, or the log-in was initiated by user sending in login and password withrememberMe
flag.
Type: Function
Verify a grant token issued by req.identity.logIn()
.
Possible use case: Service 1 plays the role of authentication authority in a SOA application. Clients get logged in with credentials or a refresh token in Service 1 and receive grant tokens. Then a client tries to get an authenticated access with that grant token to another Service 2 that is part of your application. Service 2 may verify received grant token in Service 1 and receive user data stored in the token.
Parameters:
{String} grantToken
Grant token.
Returns: {Promise<Object|null>}
{String} id
User ID{String} roles
Comma separated list of user roles{Object} claims
Collection of other claims stored in the token