Passport in Nodejs

I have the auth_usr_ctrl class

/controllers/auth_usr_ctrl

index.js in the root I call the class.method

app.post('/login', (req, res) => auth_usr.findUser(req))
//auth_usr_ctrl
const db = require('../models/index')
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

class auth_usr_ctrl{
   
 async findUser(req) {
  
       passport.use( new LocalStrategy(
       function (username, password,  done) {    
            console.log('Made it here') 
            db.AUTH_USR.findOne({
            user_name : username,
            password :  password
            }, 
            function(err, user){
                if (err){
                    console.log('No User');
                    return done(err)
                }
                if (!user){
                    return done(null, false)
                }

            } 
            )
        }
        ))
    }
}

Half based it off this article

It just freezes and returns nothing.

So the question is can I put the passport in my controller and how do I get it to find my user

using sequilze, mysql

Hi @soonerdm1, your findUser() route handler doesn’t handle the response at all, so the request just hangs until it times out. The way to incorporate passport is as follows:

  • Register a strategy at the root level of your application (not inside a route handler such as whenever you receive a request to /login)
  • Then pass passport.authenticate('local') as an express middleware
  • Finally add an actual route handler that responds with (or redirects to) a success page; this route handler will only get called if the authentication was successful according to the previously registered strategy

So together it should look something like this:

passport.use(new LocalStrategy(
  function (username, password, done) {
    console.log('Made it here')

    db.AUTH_USR.findOne({
      user_name: username,
      password: password
    }, function (err, user) {
      if (err) {
        console.log('No User')
        return done(err)
      }
      if (!user) {
        return done(null, false)
      }
    })
  }
))

app.post(
  '/login',
  passport.authenticate('local', { failureRedirect: '/login' }),
  function (req, res) {
    // Handle the response here
    res.redirect('/')
  }
)
1 Like

I’m going to start from the top so I understand this better. I appreciate your help. Let me know if you have a donation link :smiley:

In my index.js file I have all the calls and requires to make this work so we’ll skip on down to the serialize and the unserialize

passport.serializeUser(function(user, cb) {
  cb(null, user.id);
});

passport.deserializeUser(function(id, cb) {
  User.findById(id, function(err, user) {
    cb(err, user);
  });
});

First, how is the user.id getting into the passport.serializeUser? Is this called when
passport.use(new LocalStrategy() is called from the get.post(‘/login’, passport.authenticate…) ?

Same question on the deserializeUser() How are we passing an id to what would be my AUTH_USR.findById(id)??? when we only have username and password from the req.body.username, …

passport.use(new LocalStrategy(
  function (username, password, done) {
    console.log('Made it here')

    db.AUTH_USR.findOne({
      user_name: username,
      password: password
    }, function (err, user) {
      if (err) {
        console.log('No User')
        return done(err)
      }
      if (!user) {
        return done(null, false)
      }
    })
  }
))

How does the below pass in my req.body username and password?

app.post(
  '/login',
  passport.authenticate('local', { failureRedirect: '/login' }),
  function (req, res) {
    // Handle the response here
    res.redirect('/')
  }
)

And if you have time, if I didn’t want to put this in my index and just make it and end point of access denied or return the user object how would I post to that ?

It is used to store and identify the user in the session; it’s getting called under the hood to keep the authentication active without having to log in all the time. The user ID is a good and simple choice here but it may be any unique identifier, such as the e.g. the email or whatever you’re using as primary key.

BTW I just noticed that you also forgot to call done(null, user) in the verify callback – this is required for a successful login, and that user object is then also used to serialize the user to the session (not just the form data from the login request).

It’s getting passed whatever you chose to serialize the user from.

The username and password are available as req.user – try res.json(req.user) to output the complete user object.

Almost there.
this hangs up. I’m pretty sure its my deserialization function

passport.serializeUser(function (user, done) {
    console.log(user.user_id + '<- serialize' );
    done(null, user.user_id);
});

passport.deserializeUser(function (id, done) {
  auth_usr.findById(id, function(err, user){
    done(err, user)
  })
});
 
// passport local strategy for local-login, local refers to this app
passport.use('local-login', new LocalStrategy(
    function (username, password, done) {
      auth_usr.findOne(username).then(user => {console.log(user); return done(null, user)})
      .catch(error => { return done(null, false, {"message" : "No User" })})
    })
); 

My findById function

  async findById(id){
        return await db.AUTH_USR.findOne(
            {where : {user_id: id}}
        )
        .then(user => {return user} )
        .catch(error => {console.log(error)})
    }

Why would it hang?

Your findById() function doesn’t take a callback but returns a promise.

How would I write that method to return the user object?

I changed the deserializeuser function to this.

passport.deserializeUser(function (id, done) {
  console.log(id + '<- DS')
  db.AUTH_USR.findByPk(id, function(err, user){
    done(err, user)
  })
});

As you can see I’m logging the id just to see it hit the function and it dies console the id I log in with.

Still hanging. Not sure what to do . Below is the complete script

const db = require('./models/index.js');
var express         = require('express'),
    app             = express(),
    passport        = require('passport'),
    LocalStrategy   = require('passport-local').Strategy,
    bodyParser      = require('body-parser'),
    session         = require('express-session');
 
const auth_usr_ctrl = require('./controllers/auth_usr_ctrl');
const auth_usr = new auth_usr_ctrl(); 


// hardcoded users, ideally the users should be stored in a database
//var users = [{"id":111, "username":"amy", "password":"amyspassword"}];
 
// passport needs ability to serialize and unserialize users out of session
passport.serializeUser(function (user, done) {
    console.log(user.user_id + '<- serialize' );
    done(null, user.user_id);
});
passport.deserializeUser(function (id, done) {
  console.log(id + '<- DS')
  db.AUTH_USR.findByPk(id, function(err, user){
    done(err, user)
  })
});
 
// passport local strategy for local-login, local refers to this app
passport.use('local-login', new LocalStrategy(
    function (username, password, done) {
      auth_usr.findOne(username).then(user => {console.log(user); return done(null, user)})
      .catch(error => { return done(null, false, {"message" : "No User" })})
    })
); 
 
// body-parser for retrieving form data
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: true }));
 
// initialize passposrt and and session for persistent login sessions
app.use(session({
    secret: "tHiSiSasEcRetStr",
    resave: true,
    saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
 
// route middleware to ensure user is logged in
function isLoggedIn(req, res, next) {
    if (req.isAuthenticated())
        return next();
 
    res.sendStatus(401);
}
 
app.get("/", function (req, res) {
    res.send("Hello!");
});
 
// api endpoints for login, content and logout
app.get("/login", function (req, res) {
    res.send("<p>Please login!</p><form method='post' action='/login'><input type='text' name='username'/><input type='password' name='password'/><button type='submit' value='submit'>Submit</buttom></form>");
});
app.post("/login", 
   passport.authenticate("local-login", { failureRedirect: "/login"}),
    function (req, res) {
        res.redirect("/content");
});
app.get("/content", isLoggedIn, function (req, res) {
    res.send("Congratulations! you've successfully logged in.");
});

app.get("/logout", function (req, res) {
    req.logout();
    res.send("logout success!");
});
 
// launch the app
app.listen(3000);
console.log("App running at localhost:3000");

Well what does db.AUTH_USR.findByPk() look like? Does it accept a callback as the 2nd argument, or does it just return a promise like that findById() method?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.