user2573690 user2573690 - 2 years ago 98
Javascript Question

How to protect route endpoints using Passport?

I am trying to build user authentication into my simple Node.js app using the tutorial here:

It works great in terms of protecting the application home page so that it can only be accessed after logging in, but I am having a really hard time restricting my REST endpoints to only logged in users. As in using Postman I can still call the end points without any authentication.

In my route I have the following:

var express = require('express');
var router = express.Router();

// if the user is authenticated
var isAuthenticated = function (req, res, next) {
if (req.isAuthenticated())
return next();
res.json("not authenticated");

* GET carlist.
router.get('/carlist', isAuthenticated, function(req, res) {
var db = req.db;
var collection = db.get('carlist');

This doesn't seem to work, even if I actually enter correct credentials I am always returned "not authenticated". What I am I missing here?


Full code here:

Thanks in advance for the help!

Answer Source

I figured it out. Since I was using a LocalStrategy the IsAuthenticated method was looking for the credentials in the session rather than at the Basic Credentials I was sending with Postman. So I needed to create the following new BasicStrategy:

var passport = require('passport');
var BasicStrategy = require('passport-http').BasicStrategy;
var Employer = require('../models/employer');
var bCrypt = require('bcrypt-nodejs');

passport.use(new BasicStrategy(
  function(username, password, done) {
    Employer.findOne({ username: username }, function (err, user) {
      if (err) { return done(err); }
      if (!user) { return done(null, false); }
      //if (!user.validPassword(password)) { return done(null, false); }

      if (!isValidPassword(user, password)){ return done(null, false); }

      return done(null, user);

    var isValidPassword = function(employer, password){
        return bCrypt.compareSync(password, employer.password);

And then use that strategy in my route like this:

router.get('/carlist', passport.authenticate('basic',  function(req, res) {
    var db = req.db;
    var collection = db.get('cars');

This would use my basic authentication credentials from Postman to connect to the website.

Thanks to Neta Meta's advice in the comments to my OP I was able to arrive to this result and a bit more reading on the Passport documentation to understand the differences between the strategies.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download