NodeJS TypeError('JwtStrategy requires a secret or key');

Viewed 27773

I have tried for the JwtStrategy implementation I have replaced the

  1. User.findOne({id: jwt_payload.id} with

  2. User.getUserById(jwt_payload._doc._id, (err, user)

which is inside user.js file The Error that i got when runnning index.js is :-

H:\rprfinal\node_modules\passport-jwt\lib\strategy.js:29
        throw new TypeError('JwtStrategy requires a secret or key');
        ^
TypeError: JwtStrategy requires a secret or key
    at new JwtStrategy (H:\rprfinal\node_modules\passport-jwt\lib\strategy.js:29:15)
    at module.exports (H:\rprfinal\config\passport.js:10:18)
    at Object.<anonymous> (H:\rprfinal\index.js:42:29)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Function.Module.runMain (module.js:605:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3
[nodemon] app crashed - waiting for file changes before starting...

inside user.js file:-

module.exports.getUserById = function(id, callback){
    User.findById(id, callback);
}

index.js file :-

     //Body parser Middleware
app.use(bodyParser.json());

    //Passport Middleware 
app.use(passport.initialize());
app.use(passport.session());

require('./config/passport')(passport);

app.use('/users',users);

passport.js file:-

const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const User = require('../models/user');
const config = require('../config/database');

module.exports = function(passport){
    let opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
    opts.secretOrKey = config.secret;
    passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
        User.getUserById(jwt_payload._doc._id, (err, user) => {
            if(err){
                return done(err, false);
            }
            if(user){
                return done(null, user);
            } else{
                return done(null, false);
            }
        });
    }));
}

and users.js which contains Register and Authenticate

 // Authenticate
router.post('/authenticate',(req, res, next) => {
const username = req.body.username;
const password =req.body.password;

User.getUserBYUsername(username, (err, user) => {
    if(err) throw err;
    if(!user){
        return res.json({success: false,msg: 'User not found'});
    }
User.comparePassword(password,user.password, (err, isMatch) => {
  if(err) throw err;
  if(isMatch){
      const token = jwt.sign(user, config.secret, {
          expiresIn: 604800 // 1 Week
      });

    res.json({
        success: true,
        token: 'JWT '+token,
        user: {
            id: user._id,
            name:user.name,
            username: user.username,
            email: user.email
        }
    });
  } else {
       return res.json({success: false, msg: 'Wrong password'});
   } 
});
});
});
5 Answers

Met the same issue. It was just because the first options argument passed to JwtStrategy must have a valid secretOrKey. Leaving the secretOrKey undefined will give you the error.

In my case I use dotenv to read process.env variables, and must make sure require('dotenv').config(); is called before accessing process.env.SECRET.

require('dotenv').config();
const jwtOptions = {
    jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
    secretOrKey: process.env.SECRET
};
const strategy = new JwtStrategy(jwtOptions, function (payload, done) {
    // ...
});

I had this problem for importing wrong in local.strategy:

//incorrect
import { Strategy } from 'passport-jwt';

//correct
import { Strategy } from 'passport-local';

crate a keys.js file as follows

module.exports = {    
    secretOrKey: 'yoursecretkeyishere'
};

(note: secretOrKey: String or buffer containing the secret or PEM-encoded public key. Required unless secretOrKeyProvider is provided. * secretOrKeyProvider: callback in the format secretOrKeyProvider(request, rawJwtToken, done), *
which should call done with a secret or PEM-encoded public key *
(asymmetric) for the given undecoded jwt token string and request * combination. done has the signature function done(err, secret). *
REQUIRED unless secretOrKey is provided. )

in file passport.js

const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const mongoose = require('mongoose');
const User = mongoose.model('users');
const keys = require('../config/keys');

const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = keys.secretOrKey;

module.exports = passport => {
  passport.use(
    new JwtStrategy(opts, (jwt_payload, done) => {
      //Your logic here
    })
  );
};``

thats all you need to do

I have same error. solution: I have put values in quotes when create any environment variables, that was my mistake . So put values without quotes , double quotes will automatically be added. THIS IS IN CASE OF WINDOW.

Note: I have used dotenv library as mentioned in a solution , but it won't work in my case. thanku

Related