passport-jwt-cookiecombo
Passport strategy for lightning-fast authenticating
with a JSON Web Token, based on the JsonWebToken implementation
for node.js.
JWT Cookie Combo Strategy for Passport combines the authorization header for
native app requests and a more secure secured, http-only, same site, signed and
stateless cookie for web requests from a browser.
The best: Every single request saves both techniques a database query, because
the user comes from the token. You just use req.user
in your actions.
Install
npm install passport-jwt-cookiecombo
TL;DR
var JwtCookieComboStrategy = require('passport-jwt-cookiecombo');
passport.use(new JwtCookieComboStrategy({
secretOrPublicKey: 'StRoNGs3crE7'
}, (payload, done) => {
return done(null, payload.user);
}));
var jwt = require('jsonwebtoken');
router.post('/login', passport.authenticate('local'), (req, res) => {
jwt.sign({ user: req.user }, 'StRoNGs3crE7', (err, token) => {
if (err) return res.json(err);
res.cookie('jwt', token, {
httpOnly: true,
sameSite: true,
signed: true,
secure: true
});
return res.json({
jwt: token
});
});
});
var express = require('express');
app.use('/api/v1', passport.authenticate('jwt-cookiecombo', {
session: false
}), (req, res, next) => {
return next();
});
Usage
Sample Login with Set-Cookie
var cookieParser = require('cookie-parser');
var passport = require('passport');
var jwt = require('jsonwebtoken');
var express = require('express');
var app = express();
app.use(cookieParser(config.jwt.secret));
router.post('/login', passport.authenticate('local', {
session: false
}), (req, res) => {
jwt.sign({
user: req.user
}, config.jwt.secret, config.jwt.options, (err, token) => {
if (err) return res.status(500).json(err);
res.cookie('jwt', token, config.jwt.cookie);
return res.json({
jwt: token
});
});
});
passport.use(new LocalStrategy({
usernameField: 'email',
session: false
}, (username, password, done) => {
User.findOne({
email: username
})
.select('password role').exec((err, user) => {
if (err) return done(err);
if (user && user.verifyPassword(password)) return done(null, {
id: user._id,
role: user.role
});
return done(null, false);
});
}));
JWT Cookie Combo Passport Strategy
var JwtCookieComboStrategy = require('passport-jwt-cookiecombo');
passport.use(new JwtCookieComboStrategy({
secretOrPublicKey: config.jwt.secret,
jwtVerifyOptions: config.jwt.options,
passReqToCallback: false
}, (payload, done) => {
return done(null, payload.user, {});
}));
The following possible options for a JsonWebToken will be directly passed on to jsonwebtoken.verify.
secretOrPublicKey:
is a string or buffer containing either the secret for HMAC algorithms, or the PEM
encoded public key for RSA and ECDSA.
jwtVerifyOptions: {
algorithms
: List of strings with the names of the allowed algorithms. For instance, ["HS256", "HS384"]
. Default: HS256
.audience
: if you want to check audience (aud
), provide a value hereissuer
(optional): string or array of strings of valid values for the iss
field.ignoreExpiration
: if true
do not validate the expiration of the token.ignoreNotBefore
...subject
: if you want to check subject (sub
), provide a value hereclockTolerance
: number of second to tolerate when checking the nbf
and exp
claims, to deal with small clock differences among different servers
}
JWT Cookie Combo global API routes protection
app.use('/api/v1', passport.authenticate('jwt-cookiecombo', {
session: false
}), (req, res, next) => {
return next();
});
Sample Config
module.exports = {
jwt: {
secret: process.env.JWT_SECRET || 'SetStrongSecretInDotEnv',
options: {
audience: 'https://example.io',
expiresIn: '12h',
issuer: 'example.io'
},
cookie: {
httpOnly: true,
sameSite: true,
signed: true,
secure: true
}
}
};
Key | Token |
---|
Authorization | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiNTc5ZWVkZGRlMDEzNz... |
Sample Token
{
"alg": "HS256",
"typ": "JWT"
}
PAYLOAD: DATA
{
"user": {
"id": "577839eeddde013794ae2332",
"role": "admin"
},
"iat": 1468340405,
"exp": 1468383605,
"aud": "https://example.io",
"iss": "example.io"
}
VERIFY SIGNATURE
HMACSHA256 (
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
License
ISC