Abderrahman Hilali
Abderrahman Hilali

Reputation: 221

create a custom passport-jwt strategy middleware callback

I want to create a custom middleware for passport-jwt to handle authentication.

here is what I have done to create my own middleware :

var models  = require('../models');
var passport = require("passport");  
var passportJWT = require("passport-jwt");  
var config = require("../config/config.json");  
var ExtractJwt = passportJWT.ExtractJwt;  
var Strategy = passportJWT.Strategy;  
var params = {  
    secretOrKey: config.jwtSecret,
    jwtFromRequest: ExtractJwt.fromAuthHeader()
};

/**
 * jwt authentication strategy
 */
var strategy = new Strategy(params, function(payload, done) {
    models.User.findById(payload.id)
    .then((user)=>{
        if (user) {
            return done(null, {
                id: user.id,
                username : user.username
            });
        } else {
            return done(new Error("User not found"), false);
        }
    }).catch((err)=>{
        return done(err, false);
    });
});
passport.use(strategy);

module.exports =  {  
    initialize: function() {
        return passport.initialize();
    },
    authenticate: (req, res, next)=>{
        passport.authenticate('jwt', { session: false }, (err, user, info)=>{ 
            if (err) { return next(err); } 
            if (!user) { return res.send("Custom Unauthorised").end(); } 
            // edit as per comment
            //return res.send("Test Route Accessed").end();
            req.user = user;   // Forward user information to the next middleware
            next();
        })(req, res, next);
    }
};

but everytime I type 'npm start' to run the app I face this error :

if (request.headers[AUTH_HEADER]) { ^ TypeError: Cannot read property 'headers' of undefined.

the authorization header is set in the request.

Upvotes: 2

Views: 6434

Answers (1)

Abderrahman Hilali
Abderrahman Hilali

Reputation: 221

yes I did Find the answer here it is :

first define the strategy logic:

 var strategy = new Strategy(params, function (payload, done) {
    //finding the user in the database
    console.log(payload);
    models.users.findById(parseInt(payload.userId))
        .then((user) => {
            //if the user is found
            if (user) {
                return done(null, {
                    id: user.id,
                    username: user.username
                });
            } else {
                return done(new Error("User not found"), null);
            }
        }).catch((err) => {
        console.log(err);
            return done(new Error("uncaught error! try again later"), null);
        })
});

then make passport use that strategy"

passport.use(strategy);

and finally export the initialization function and the middleware function

    module.exports = {
    initialize: function () {
        return passport.initialize();
    },
    authenticate: function (req, res, next) {
        return passport.authenticate("jwt", {
            session: false
        }, (err, user, info) => {
            if (err) {
                console.log(err);
                return next(err);
            }
            if (!user) {
                return res.json({
                    status: 'error',
                    error: 'ANOTHORIZED_USER'
                });
            }
            // Forward user information to the next middleware
            req.user = user; 
            next();
        })(req, res, next);
    }
};

and then you can call the function authenticate defined above as a middleware in your routes.

here is an example :

//import the express router
var express = require('express');
var router = express.Router();
//here I am importing the functions defined above, I put them in the config folder
var jwt_login_strategy = require('../config/jwt-login-strategy');
//and finally use the jwt_login_strategy as a middleware
router.post('something', jwt_login_strategy.authenticate, your_other_middleware(req, res, next)=>{...});

you have to call the authenticate function without adding parentheses, just like this jwt_login_strategy.authenticate.

hope it will solve your problem as it did for mine.

Upvotes: 6

Related Questions