title: Node.js - JWT, API: How To Implement Multiple Passport.js Authentication Middleware?
body: <p>So I am trying to build two JWT authentication systems for one app. One for the users and one for businesses. The authentication uses passport (local and JWT). I started working on the user aspect of the authentication and I was able to make it work as I wanted. I thought it would be the same for business. All I did was simply copy paste and change few variable. Normally the business endpoints should work but it does not. So I tried to debug what was going on and I am still trying to figure out what it is. My guess is that when I load the strategies in my app.js, only the passport strategies for users get called. If I permute positions between <code>passport</code> and <code>business-passport</code>, everything breaks.   </p>
  
  <p>Here is my code.  </p>
  
  <p><strong>Passport Middleware For User</strong> passport.js</p>
  
  <pre><code>const passport = require('passport');
  const JwtStrategy = require('passport-jwt').Strategy;
  const {ExtractJwt} = require('passport-jwt');
  const LocalStrategy = require('passport-local').Strategy;
  const { JWT_SECRET } = require('./config');
  const User = require('./models/user');
  // const Business = require('./models/business');
  
  passport.use(new JwtStrategy({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: JWT_SECRET,
      passReqToCallback: true
  }, async (req, payload, done) =&gt; {
      console.log('payload', payload)
  
      try {
          // Find the user specified in token
          const user = await User.findById(payload.sub);
  
          // Handle if User dont exist
          if (!user) {
              return done(null, false);
          }
  
          // Otherwise, return the user
          req.user = user;
          done(null, user);
      } catch (error) {
          done(error, false);
      }
  
  }));
  // Local Strategy
  passport.use(new LocalStrategy({
      usernameField: 'email'
  }, async (email, password, done) =&gt; {
  
      try {
          // Find the user given the email
          const user = await User.findOne({email});
  
          // If not, handle it
          if (!user) {
              return done(null, false);
          }
  
          // check if password is correct
  
          const isMatch = await user.isValidPassword(password);
  
          // if not, handle it
          if (!isMatch) {
              return done(null, false);
          }
  
          // Otherwise, return the user
          done(null, user);
  
      } catch (error) {
          done(error, false);
      }
  
  }));
  </code></pre>
  
  <p><strong>Passport Middleware For Business</strong>  passport-business.js</p>
  
  <p>Just change User for Business  </p>
  
  <p><strong>Controllers for Users</strong>  controllers/user.js  </p>
  
  <pre><code>const fs = require('fs');
  const mongoose = require('mongoose');
  const JWT = require('jsonwebtoken');
  const { JWT_SECRET } = require('../config');
  
  const User = require('../models/user');
  
  signToken = user =&gt; {
      // Respond with token
      return JWT.sign({
          iss: 'My Business, Inc.',
          userType: 'users',
          sub: user._id, /* You can also use newUser.id */
          iat: new Date().getTime(), /* Current Time */
          exp: new Date().setDate(new Date().getDate() + 1), /* Current Time + 1 day ahead */
      }, JWT_SECRET);
  };
  
  module.exports = {
  
      signup: async (req, res, next) =&gt; {
          console.log('req.value.body', req.value.body);
  
          const {email, password} = req.value.body;
  
          // Check if User already exist by email address
          const foundUser = await User.findOne({email});
          if(foundUser) {
              return res.status(403).json({error: 'Email is already in use'});
          }
  
          // Create a new User
          const newUser = new User({email, password});
          await newUser.save();
  
          // Generate the token
          const token = signToken(newUser);
  
          // Respond with token
          res.status(200).json({token});
      },
      signin: async (req, res, next) =&gt; {
          // Generate token
          const token = signToken(req.user);
          res.status(200).json({token});
          // console.log('signin');
      },
  };
  </code></pre>
  
  <p>The reason why I have <code>req.value...</code> is because of a middleware that I used to validate my body and url params.  </p>
  
  <p><strong>Controllers for Business</strong>  controllers/business.js . 
  Everything is the same, just change User with Business.    </p>
  
  <p>I should also point out that whenever I use jwt.io to see if my token signature is valid, it always says <code>invalid signature</code>, but everything works on my application as expected. Wondering why it is saying <code>invalid signature</code>.   </p>
  
  <p><strong>Routes for Users</strong> routes/user.js . Please remember that it is the same for Business.  </p>
  
  <pre><code>const express = require('express');
  
  // this router deals better with "try{} catch{}" situations"
  const router = require('express-promise-router')();
  
  const passport = require('passport');
  
  const UserController = require('../controllers/user');
  
  require('../passport');
  
  const { validateBody, schemas, validateParam } = require('../helpers/route-helpers');
  
  const StrategyLocal = passport.authenticate('local', {session: false});
  const StrategyJWT = passport.authenticate('jwt', {session: false});
  
  router.get('/', (req, res) =&gt; {
  
      res.json({message: "Welcome to our User's API Endpoint!"});
  });
  
  router.route('/signup')
      // .get(UserController.index)
      .post([validateBody(schemas.authSchema)], UserController.signup);
  router.route('/signin')
      // Makes sense to implement localstrat here because jWt will always work because the user was issued a token at signup
      // So both solutions will work here as a strategy
      .post(validateBody(schemas.authSchema), StrategyLocal, UserController.signin);
  
  module.exports = router;   
  </code></pre>
  
  <p>And finally, the file that I think is causing the problem... Introducing...<br>
  <strong>app.js</strong></p>
  
  <pre><code>const express = require('express');
  const logger = require('morgan');
  const mongoose = require('mongoose');
  const bodyParser = require('body-parser');
  const passport = require('passport');
  const path = require('path');
  const cors = require('cors');
  
  const { dbName } = require('./config');
  
  mongoose.Promise = global.Promise;
  mongoose.connect('mongodb://localhost/' + dbName, {
      useNewUrlParser:true,
      useUnifiedTopology:true,
      useCreateIndex: true,
      useFindAndModify: false
  });
  
  const app = express();
  
  //  This is where the problem is happening in my opinion
  require('./passport-business')
  require('./passport')
  
  
  const user = require('./routes/user');
  const business = require('./routes/business');
  
  // Middlewares
  // set the static files location /public/img will be /img for users
  app.use(logger('dev'));
  app.use(cors());
  app.use(bodyParser.urlencoded({ extended: false}));
  app.use(bodyParser.json());
  
  app.use((req, res, next) =&gt; {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, noauth");
      if (req.method === 'OPTIONS'){
          res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, OPTIONS");
          res.setHeader('Access-Control-Allow-Credentials', false);
          return res.status(200).json({});
      }
      next();
  });
  
  app.use('/api/users', user);
  app.use('/api/businesses', business);
  
  
  // Start the server
  
  const port =  app.get('port') || 2019;
  app.listen(port, () =&gt; console.log(`Server is listening on port ${port}`));
  </code></pre>
  
  <p>If I keep everything as is, all User endpoints work, signup works for Business, but I get 401 when I try to signin (Business). But if I do this...  </p>
  
  <pre><code>require('./passport')
  require('./passport-business')    
  </code></pre>
  
  <p>I get 401 when I try to signin (User) and I get 500 when I try to signin (Business).<br>
  Can someone tell me what I am doing wrong here? Maybe it is the order in which I load these files in app.js. Maybe it is the fact that I am creating two separate <code>passport</code> files for User and Business. <strong>I would love to know how to combine those two into one.</strong> . </p>