pjc

passport-jwt-cookiecombo

JSON Web Token (JWT) cookie combo authentication strategy for Passport and Node.js.

Showing:

Popularity

Downloads/wk

2.3K

GitHub Stars

31

Maintenance

Last Commit

5yrs ago

Contributors

2

Package

Dependencies

2

Size (min+gzip)

103.5KB

License

ISC

Type Definitions

Tree-Shakeable

No?

Categories

Deprecated!
Package no longer supported. Contact support@npmjs.com for more info.

Readme

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

// =============================================================================
// Configure Strategy
// =============================================================================
var JwtCookieComboStrategy = require('passport-jwt-cookiecombo');

passport.use(new JwtCookieComboStrategy({
    secretOrPublicKey: 'StRoNGs3crE7'
}, (payload, done) => {
    return done(null, payload.user);
}));
// =============================================================================
// Sign Token
// =============================================================================
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);

        // Send Set-Cookie header
        res.cookie('jwt', token, {
            httpOnly: true,
            sameSite: true,
            signed: true,
            secure: true
        });
        
        // Return json web token
        return res.json({
            jwt: token
        });
    });
});
// =============================================================================
// Authenticate Requests
// =============================================================================
var express = require('express');

app.use('/api/v1', passport.authenticate('jwt-cookiecombo', {
    session: false
}), (req, res, next) => {
    return next();
});

Usage

// =============================================================================
// Dependencies
// =============================================================================
var cookieParser = require('cookie-parser');
var passport = require('passport');
var jwt = require('jsonwebtoken');
var express = require('express');
// =============================================================================
// Express App inits cookie with a secret
// =============================================================================
var app = express();

// Pass a secret to sign the secured http cookie
app.use(cookieParser(config.jwt.secret));
// =============================================================================
// Login route with any Passport authentication strategy
// =============================================================================
// Passport provides us the authenticated user in the request
router.post('/login', passport.authenticate('local', {
    session: false
}), (req, res) => {
    // Create and sign json web token with the user as payload
    jwt.sign({
        user: req.user
    }, config.jwt.secret, config.jwt.options, (err, token) => {
        if (err) return res.status(500).json(err);

        // Send the Set-Cookie header with the jwt to the client
        res.cookie('jwt', token, config.jwt.cookie);

        // Response json with the jwt
        return res.json({
            jwt: token
        });
    });
});
// =============================================================================
// Sample Passport Authentication where the user is set for the jwt payload
// =============================================================================
passport.use(new LocalStrategy({
    // My users have only email
    usernameField: 'email',
    session: false
}, (username, password, done) => {
    User.findOne({
        email: username
    })
    // Explicitly select the password when the model hides it
    .select('password role').exec((err, user) => {
        if (err) return done(err);
        
        // Copy the user w/o the password into a new object
        if (user && user.verifyPassword(password)) return done(null, {
            id: user._id,
            role: user.role
        });

        return done(null, false);
    });
}));
var JwtCookieComboStrategy = require('passport-jwt-cookiecombo');

// Authenticate API calls with the Cookie Combo Strategy
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 here
  • issuer (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 here
  • clockTolerance: number of second to tolerate when checking the nbf and exp claims, to deal with small clock differences among different servers

}

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', // 1d
            issuer: 'example.io'
        },
        cookie: {
            httpOnly: true,
            sameSite: true,
            signed: true,
            secure: true
        }
    }
};

Sample Auth-Header

KeyToken
AuthorizationeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiNTc5ZWVkZGRlMDEzNz...

Sample Token

HEADER: ALGORITHM & TOKEN TYPE
{
    "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
)

Tonic Notebook

Try it out on tonic.dev tonic + npm: passport-jwt-cookiecombo

License

ISC

Rate & Review

Great Documentation0
Easy to Use0
Performant0
Highly Customizable0
Bleeding Edge0
Responsive Maintainers0
Poor Documentation0
Hard to Use0
Slow0
Buggy0
Abandoned0
Unwelcoming Community0
100
No reviews found
Be the first to rate

Alternatives

No alternatives found

Tutorials

No tutorials found
Add a tutorial