passport-jwt

repository·master·Indexed 24 days ago

https://github.com/mikenicholson/passport-jwt

A Passport.js authentication strategy for securing RESTful endpoints using JSON Web Tokens (JWT) in a stateless manner. It includes the JwtStrategy for token verification and the ExtractJwt utility to retrieve tokens from HTTP headers, body fields, URL query parameters, or custom sources.

Tokens
2.5K
Snippets
5
Records
17
Agent score
84%

What's inside passport-jwt

  1. Authenticate requests using JWT

    master

    To protect an endpoint, use passport.authenticate() with the strategy name 'jwt'. For stateless RESTful APIs, it is recommended to set { session: false }.

    app.post('/profile', passport.authenticate('jwt', { session: false }),
        function(req, res) {
            res.send(req.user.profile);
        }
    );
  2. Migrate from passport-jwt 3.x.x to 4.x.x

    master

    Version 4.0.0 updated the underlying jsonwebtoken dependency from v7 to v8. Because passport-jwt exposes the jsonwebtoken API via the jsonWebTokenOptions constructor option, changes in jsonwebtoken may affect your configuration.

    The most significant change is likely the change in units for the maxAge attribute within jsonWebTokenOptions. Refer to the jsonwebtoken v7-to-v8 migration notes for full details on all API changes.

  3. Migrate from passport-jwt 1.x.x to 2.x.x

    master

    The v2 API introduced the concept of JWT extractor functions, breaking backwards compatibility with v1.

    To achieve identical behavior to v1, use the ExtractJwt.versionOneCompatibility(options) extractor. The options object supports the following keys:

    • tokenBodyField: Field in a request body to search for the JWT (default: auth_token).
    • tokenQueryParameterName: Query parameter name containing the token (default: auth_token).
    • authScheme: Expected authorization scheme if token is submitted through the HTTP Authorization header (default: JWT).

    Example migration:

    v1 implementation:

    var JwtStrategy = require('passport-jwt').Strategy;
    var opts = {}
    opts.tokenBodyField = 'MY_CUSTOM_BODY_FIELD';
    opts.secretOrKey = 'secret';
    opts.issuer = 'accounts.examplesoft.com';
    opts.audience = 'yoursite.net';
    passport.use(new JwtStrategy(opts, verifyFunction));

    v2 implementation using compatibility extractor:

    var JwtStrategy = require('passport-jwt').Strategy,
        ExtractJwt = require('passport-jwt').ExtractJwt;
    var opts = {}
    opts.jwtFromRequest = ExtractJwt.versionOneCompatibility({ tokenBodyField = 'MY_CUSTOM_BODY_FIELD' });
    opts.opts.secretOrKey = 'secret';
    opts.issuer = 'accounts.examplesoft.com';
    opts.audience = 'yoursite.net';
    passport.use(new JwtStrategy(opts, verifyFunction));
  4. Migrate from passport-jwt 2.x.x to 3.x.x

    master

    Version 3.0.0 removed the ExtractJwt.fromAuthHeader() function because its default 'jwt' scheme was not RFC 6750 compliant.

    To migrate:

    • Use ExtractJwt.fromAuthHeaderAsBearerToken() for standard Bearer token extraction.
    • If you need to maintain the exact behavior of the old fromAuthHeader() (using the 'jwt' scheme), replace it with ExtractJwt.fromAuthHeaderWithScheme('jwt').
  5. Write a custom extractor function

    master

    If the built-in extractors do not meet your needs, you can provide a custom callback function to jwtFromRequest. For example, to extract a JWT from a cookie using cookie-parser:

    var cookieExtractor = function(req) {
        var token = null;
        if (req && req.cookies) {
            token = req.cookies['jwt'];
        }
        return token;
    };
    
    var opts = { jwtFromRequest: cookieExtractor };
    var cookieExtractor = function(req) {
        var token = null;
        if (req && req.cookies) {
            token = req.cookies['jwt'];
        }
        return token;
    };
    // ...
    opts.jwtFromRequest = cookieExtractor;
  6. Configure the JwtStrategy

    master

    The JwtStrategy is initialized with new JwtStrategy(options, verify).

    options is an object used to control token extraction and verification. verify is a callback function that handles the decoded payload.

    Options Reference

    OptionRequirementDescription
    secretOrKeyRequired*A string or buffer containing the secret (symmetric) or PEM-encoded public key (asymmetric) for verifying the signature.
    secretOrKeyProviderRequired*A callback function(request, rawJwtToken, done) that calls done(err, secret) with the key.
    jwtFromRequestREQUIREDA function that accepts a request and returns the JWT string or null.
    issuerOptionalVerifies the token issuer (iss) against this value.
    audienceOptionalVerifies the token audience (aud) against this value.
    algorithmsOptionalA list of allowed algorithm names, e.g., ["HS256", "HS384"].
    ignoreExpirationOptionalIf true, the expiration of the token is not validated.
    passReqToCallbackOptionalIf true, the request object is passed as the first argument to the verify callback.
    jsonWebTokenOptionsOptionalAn object containing options passed directly to the underlying jsonwebtoken verifier (e.g., maxAge).

    Note: secretOrKey and secretOrKeyProvider are mutually exclusive; one must be provided.

    Verify Callback Signature

    verify(jwt_payload, done)

    • jwt_payload: An object containing the decoded JWT payload.
    • done: A Passport-style callback: done(error, user, info).
    var JwtStrategy = require('passport-jwt').Strategy,
        ExtractJwt = require('passport-jwt').ExtractJwt;
    
    var opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
    opts.secretOrKey = 'secret';
    opts.issuer = 'accounts.examplesoft.com';
    opts.audience = 'yoursite.net';
    
    passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
        User.findOne({id: jwt_payload.sub}, function(err, user) {
            if (err) {
                return done(err, false);
            }
            if (user) {
                return done(null, user);
            } else {
                return done(null, false);
            }
        });
    }));
  7. Extract the JWT from a request

    master

    The jwtFromRequest option requires an extractor function that accepts a request object and returns the JWT string or null. You can use the built-in factory functions provided by passport-jwt.ExtractJwt or write a custom function.

    Built-in Extractors (ExtractJwt)

    • ExtractJwt.fromHeader(header_name): Looks for the JWT in the specified HTTP header.
    • ExtractJwt.fromBodyField(field_name): Looks for the JWT in a specific body field (requires a body parser).
    • ExtractJwt.fromUrlQueryParameter(param_name): Looks for the JWT in a URL query parameter.
    • ExtractJwt.fromAuthHeaderWithScheme(auth_scheme): Looks in the Authorization header, matching the provided scheme.
    • ExtractJwt.fromAuthHeaderAsBearerToken(): Looks in the Authorization header using the bearer scheme.
    • ExtractJwt.fromExtractors([array]): Attempts multiple extractors in order until one returns a token.
  8. Extract JWT from the Authorization header with a specific scheme

    master
    Use fromAuthHeaderWithScheme(auth_scheme) to create an extractor that looks for a token in the Authorization header, matching a specific scheme (e.g., 'JWT' or 'Bearer'). It uses the internal auth_header parser to split the scheme and the token value.
  9. Use versionOneCompatibility for legacy migration

    master

    If migrating from v1.., use versionOneCompatibility(options) to mimic the old extraction logic. This extractor follows a specific fallback order:

    1. The Authorization header (using the provided authScheme).
    2. The request body (using the provided tokenBodyField).
    3. The URL query parameters (using the provided tokenQueryParameterName).

    Default values if options are not provided:

    • authScheme: 'JWT'
    • tokenBodyField: 'auth_token'
    • tokenQueryParameterName: 'auth_token'