Passportjs hangs on serializeUser

passport js
passport-local
passport js tutorial
passport npm
passport-jwt
passport failureflash
passport.authenticate not working
passport deserializeuser not called

I'm currently learning how to authenticate users using Passportjs and a local strategy, I've been following the tutorial here: https://scotch.io/tutorials/easy-node-authentication-setup-and-local. I've made some changes to use sequelize instead of mongoose, and now when I log in I get redirected to a blank error page.

The console logs show:

Login Requested
Executing (default): SELECT `id`, `localemail`, `localpassword`, 
`facebookid`, `facebooktoken`, `facebookname`, `facebookemail`, 
`twitterid`, `twittertoken`, `twitterdisplayname`, `twitterusername`, 
`googleid`, `googletoken`, `googleemail`, `googlename`, `createdAt`, 
`updatedAt` FROM `Users` AS `User` WHERE `User`.`localemail` = 
'test@test.co.uk' LIMIT 1;
User found and logged in: 6
Serializing User: 6
POST /login 302 118.674 ms - 60
Executing (default): SELECT `id`, `localemail`, `localpassword`, 
`facebookid`, `facebooktoken`, `facebookname`, `facebookemail`, 
`twitterid`, `twittertoken`, `twitterdisplayname`, `twitterusername`, 
`googleid`, `googletoken`, `googleemail`, `googlename`, `createdAt`, 
`updatedAt` FROM `Users` AS `User` WHERE `User`.`id` = 6;

I believe I've narrowed the issue down to between when the serializeUser function is called and before the page is rendered, here is my passport-config file:

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const User = require('../models/user');
const bcrypt= require('bcrypt-nodejs');

passport.serializeUser(function(user, done) {
  console.log('Serializing User: ' + user.id);
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.user.findOne({where: {id: id}}).then(function(err, user) {
    return done(err, user);
  }).catch(function(err) {
    return done(err);
  });
});

passport.use('local-signup', new LocalStrategy({
  usernameField: 'email',
  passwordField: 'password',
  passReqToCallback: true,
  },
  function(req, email, password, done) {
    process.nextTick(function() {
      User.user.findOne({where: {localemail: email}}).then(function(user) {
        if (user) {
          return done(null, false,
              req.flash('signupMessage', 'That email is already taken.'));
        } else {
          let newUser = new User.user();
          console.log(newUser);
          newUser.localemail = email;
          newUser.localpassword = User.generateHash(password);
          newUser.save().then(function(user) {
            return done(null, user);
          }).catch(function(err) {
            return done(err);
          });
        }
      }).catch(function(err) {
        return done(err);
      });
    });
  }
));

passport.use('local-login', new LocalStrategy({
  usernameField: 'email',
  passwordField: 'password',
  passReqToCallback: true,
  },
  function(req, email, password, done) {
    User.user.findOne({where: {localemail: email}}).then(function(user) {
      if (!user) {
        console.log('No User found!');
        return done(null, false, req.flash('loginMessage', 'No user found'));
      }
      if (!User.validPassword(password, user)) {
        console.log('Incorrect Password');
        return done(null, false, req.flash('loginMessage', 'Wrong password.'));
      }
      console.log('User found and logged in: ' + user.id);
      return done(null, user);
    }).catch(function(err) {
      return done(err);
    });
  }
));

module.exports = passport;

And the routes for login and the success redirect:

router.post('/login', function(req, res, next) {
  console.log('Login Requested');
  next();
}, passport.authenticate('local-login', {
  successRedirect: '/profile',
  failureRedirect: '/login',
  failureFlash: true,
}));

I get the same results no matter what page I go to after attempting to login, a repeat of the SQL query in the console and a blank error page. I've see a lot of issues similar to this on stackoverflow, but after trying the solutions nothing has worked.

Update

User model:

const Sequleize = require('sequelize');
const db = require('../config/database');
const bcrypt= require('bcrypt-nodejs');


let user = db.define('User', {
  localemail: Sequleize.STRING,
  localpassword: Sequleize.STRING,

  facebookid: Sequleize.STRING,
  facebooktoken: Sequleize.STRING,
  facebookname: Sequleize.STRING,
  facebookemail: Sequleize.STRING,

  twitterid: Sequleize.STRING,
  twittertoken: Sequleize.STRING,
  twitterdisplayname: Sequleize.STRING,
  twitterusername: Sequleize.STRING,

  googleid: Sequleize.STRING,
  googletoken: Sequleize.STRING,
  googleemail: Sequleize.STRING,
  googlename: Sequleize.STRING,
});

db.sync();

exports.validPassword = function(password, user) {
  return bcrypt.compareSync(password, user.localpassword);
};

exports.generateHash = function(password) {
  return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

exports.user = user;

## Setup Passport Login swithout deserializeUser ##

i think you have used some depreciated functions that tutorial was done 2016 , 2 years ago , loads of things can change within 2 years ,

let's redo this following the below steps , assuming that you already finished the part of installing node.js .

make folder for your app :

mkdir AuthApp cd AuthApp

create the node app : npm init

You’ll be prompted to provide some information for Node’s package.json. Just hit enter until the end to leave the default configuration.

Next, we’ll need an HTML file to send to the client. Create a file called auth.html in the root folder of your app, not going to use so much html as we are going to do it for testing :

<html>
<head>
<title>Node.js OAuth</title>
</head>
<body>
<a href=auth/facebook>Sign in with Facebook</a>
<br></br>
<a href=auth/github>Sign in with Github</a>
</body>
</html>

You’ll also require Express, a framework for building web apps that’s inspired by Ruby’s Sinatra. In order to install Express, from the terminal type the following command:

npm install express --save Once you’ve done that, it’s time to write some code.

Create a file index.js in the root folder of your app and add the following content to it:

/*  EXPRESS SETUP  */
const express = require('express');
const app = express();
app.get('/', (req, res) => res.sendFile('auth.html', { root : __dirname}));
const port = process.env.PORT || 3000;
app.listen(port , () => console.log('App listening on port ' + port));

In the code above, we require Express and create our Express app by calling express(). Then we declare the route for the home page of our app. There we send the HTML file we’ve created to the client accessing that route. Then, we use process.env.PORT to set the port to the environment port variable if it exists. Otherwise, we’ll default to 3000, which is the port we’ll be using locally. This gives you enough flexibility to switch from development, directly to a production environment where the port might be set by a service provider like, for instance, Heroku. Right below, we call app.listen() with the port variable we set up, and a simple log to let us know that it’s all working fine, and on which port is the app listening.

Now we should start our app to make sure all is working correctly. Simply write the following command on the terminal:

node index.js You should see the message: App listening on port 3000. If that’s not the case, you probably missed a step. Go back and try again.

Moving on, let’s see if our page is being served to the client. Go to your web browser and navigate to http://localhost:3000.

If you can see the page we created in auth.html, we’re good to go.

Head back to the terminal and stop the app with ctrl + c. So remember, when I say start the app, you write node index.js, and when I say stop the app, you do ctrl + c. Clear? Good, you’ve just been programmed :-)

Setting up Passport As you’ll soon come to realize, Passport makes it a breeze to provide authentication for our users. Let’s install Passport with the following command:

npm install passport --save Now we have to set up Passport. Add the following code at the bottom of the index.js file:

/*  PASSPORT SETUP  */

const passport = require('passport');
app.use(passport.initialize());
app.use(passport.session());
app.get('/success', (req, res) => res.send("You have successfully logged in"));
app.get('/error', (req, res) => res.send("error logging in"));

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

passport.deserializeUser(function(obj, cb) {
cb(null, obj);
});

Here we require Passport and initialize it along with its session authentication middleware, directly inside our Express app. Then, we set up the '/success' and '/error' routes, which will render a message telling us how the authentication went. It’s the same syntax for our last route, only this time instead of using res.SendFile() we’re using res.send(), which will render the given string as text/html in the browser. Then we’re using serializeUser and deserializeUser callbacks. The first one will be invoked on authentication and its job is to serialize the user instance and store it in the session via a cookie. The second one will be invoked every subsequent request to deserialize the instance, providing it the unique cookie identifier as a "credential". You can read more about that in the Passport documentation.

As a side note, this very simple sample app of ours will work just fine without deserializeUser, but it kills the purpose of keeping a session, which is something you’ll need in every app that requires login.

That’s all for the actual Passport setup. Now we can finally get onto business.

Implementing Facebook Authentication The first thing we’ll need to do in order to provide Facebook Authentication is installing the passport-facebook package. You know how it goes:

npm install passport-facebook --save

Now that everything’s set up, adding Facebook Authentication is extremely easy. Add the following code at the bottom of your index.js file:

/*  FACEBOOK AUTH  */

const FacebookStrategy = require('passport-facebook').Strategy;
const FACEBOOK_APP_ID = 'your app id';
const FACEBOOK_APP_SECRET = 'your app secret';
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, cb) {
  return cb(null, profile);
}
));

app.get('/auth/facebook',
passport.authenticate('facebook'));

app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/error' }),
function(req, res) {
res.redirect('/success');
});

Let’s go through this block of code step by step. First, we require the passport-facebook module. Then, we declare the variables in which we’ll store our app id and app secret (we’ll see how to get those shortly). After that, we tell Passport to use an instance of the FacebookStrategy we required. To instantiate said strategy we give it our app id and app secret variables and the callbackURL that we’ll use to authenticate the user. As a second parameter, it takes a function that will return the profile info provided by the user.

Further down, we set up the routes to provide authentication. As you can see in the callbackURL we redirect the user to the /error and /success routes we defined earlier. We’re using passport.authenticate, which attempts to authenticate with the given strategy on its first parameter, in this case facebook. You probably noticed that we’re doing this twice. On the first one, it sends the request to our Facebook app. The second one is triggered by the callback URL, which Facebook will use to respond to the login request.

Now you’ll need to create a Facebook app. For details on how to do that, consult Facebook’s very detailed guide Creating a Facebook App, which provides step by step instructions on how to create one.

When your app is created, go to Settings on the app configuration page. There you’ll see your app id and app secret. Don’t forget to change the variables you declared for them on the index.js file with their corresponding values.

Next, enter "localhost" in the App Domains field. Then, go to Add platform at the bottom of the page and choose Website. Use http://localhost:3000/auth/facebook/callback as the Site URL.

On the left sidebar, under the Products section, you should see Facebook Login. Click to get in there.

Lastly, set the Valid OAuth redirect URIs field to http://localhost:3000/auth/facebook/callback.

If you start the app now and click the Sign in with Facebook link, you should be prompted by Facebook to provide the required information, and after you’ve logged in, you should be redirected to the /success route, where you’ll see the message You have successfully logged in.

That’s it! you have just set up Facebook Authentication. Pretty easy, right?

Implementing GitHub Authentication The process for adding GitHub Authentication is quite similar to what we did for Facebook. First, we’ll install the passport-github module:

npm install passport-github --save

Now go to the index.js file and add the following lines at the bottom:

/*  GITHUB AUTH  */

const GitHubStrategy = require('passport-github').Strategy;

const GITHUB_CLIENT_ID = "your app id"
const GITHUB_CLIENT_SECRET = "your app secret";

passport.use(new GitHubStrategy({
clientID: GITHUB_CLIENT_ID,
clientSecret: GITHUB_CLIENT_SECRET,
callbackURL: "/auth/github/callback"
},
function(accessToken, refreshToken, profile, cb) {
  return cb(null, profile);
}
));

app.get('/auth/github',
passport.authenticate('github'));

app.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/error' }),
function(req, res) {
res.redirect('/success');
});

This looks familiar! It’s practically the same as before. The only difference is that we’re using the GithubStrategy instead of FacebookStrategy.

So far so … the same. In case you hadn’t yet figured it out, the next step is to create our GitHub App. GitHub has a very simple guide, Creating a GitHub app, that will guide you through the process.

When you’re done, in the configuration panel you’ll need to set the Homepage URL to http://localhost:3000/ and the Authorization callback URL to http://localhost:3000/auth/github/callback, just like we did with Facebook.

Now, simply restart the Node server and try logging in using the GitHub link.

End of Passport Setup proccess .

passports with serialized users where your problem exist also is covered with in this tutorial link click here to view it

javascript - Passportjs hangs on serializeUser, ## Setup Passport Login swithout deserializeUser ##. i think you have used some depreciated functions that tutorial was done 2016 , 2 years  Passport is authentication middleware for Node.js . Extremely flexible and modular, Passport can be unobtrusively dropped in to any Express -based web application. A comprehensive set of strategies support authentication using a username and password , Facebook, Twitter, and more. 500+ Strategies Now! View All Strategies.

There are two types of methods you can add to the model - 1. instance method and 2. class method. More on that here => https://medium.com/@benjaminconant/defining-instance-methods-on-sequelize-js-models-dea36f478950

You can specify your validatePassword and generateHash methods as class methods of User model like so

const Sequleize = require('sequelize');
const db = require('../config/database');
const bcrypt= require('bcrypt-nodejs');


let User = db.define('User', {
  localemail: Sequleize.STRING,
  localpassword: Sequleize.STRING,

  facebookid: Sequleize.STRING,
  facebooktoken: Sequleize.STRING,
  facebookname: Sequleize.STRING,
  facebookemail: Sequleize.STRING,

  twitterid: Sequleize.STRING,
  twittertoken: Sequleize.STRING,
  twitterdisplayname: Sequleize.STRING,
  twitterusername: Sequleize.STRING,

  googleid: Sequleize.STRING,
  googletoken: Sequleize.STRING,
  googleemail: Sequleize.STRING,
  googlename: Sequleize.STRING,
}, {
    classMethods: {
        validPassword: function(password, user) {
            return bcrypt.compareSync(password, user.localpassword);
        };

        generateHash: function(password) {
            return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
        };
    }    
});

module.exports = User;

Now, you can use User model like so

passport.deserializeUser(function(id, done) {
  User.findOne({where: {id: id}}).then(function(err, user) {
    return done(err, user);
  }).catch(function(err) {
    return done(err);
  });
});

passport.use('local-signup', new LocalStrategy({
  usernameField: 'email',
  passwordField: 'password',
  passReqToCallback: true,
  },
  function(req, email, password, done) {
    process.nextTick(function() {
      User.findOne({where: {localemail: email}}).then(function(user) {
        if (user) {
          return done(null, false,
              req.flash('signupMessage', 'That email is already taken.'));
        } else {
          let newUser = new User();
          console.log(newUser);
          newUser.localemail = email;
          newUser.localpassword = User.generateHash(password);
          newUser.save().then(function(user) {
            return done(null, user);
          }).catch(function(err) {
            return done(err);
          });
        }
      }).catch(function(err) {
        return done(err);
      });
    });
  }
)); 

passport.use('local-login', new LocalStrategy({
  usernameField: 'email',
  passwordField: 'password',
  passReqToCallback: true,
  },
  function(req, email, password, done) {
    User.findOne({where: {localemail: email}}).then(function(user) {
      if (!user) {
        console.log('No User found!');
        return done(null, false, req.flash('loginMessage', 'No user found'));
      }
      if (!User.validPassword(password, user)) {
        console.log('Incorrect Password');
        return done(null, false, req.flash('loginMessage', 'Wrong password.'));
      }
      console.log('User found and logged in: ' + user.id);
      return done(null, user);
    }).catch(function(err) {
      return done(err);
    });
  }
));

module.exports = passport;

Documentation: Configure, In order to support login sessions, Passport will serialize and deserialize user instances to and from the session. passport.serializeUser(function(user, done)  node.js authentication using passport local strategy. Passport is a node module that is used as an authentication middleware. The only purpose of this module is to authenticate requests. It abstracts away the complexity of authentication process, which makes the application code more clean and maintainable.

The problem was not with passportjs, but instead with my sequelize query in the deserializeUser method:

User.user.findOne({where: {id: id}}).then(function(err, user) { ...

The query returns only one variable which is passed to the .then() function, so changing it to this:

User.user.findOne({where: {id: id}}).then(function(user) { ..

fixed my error.

Easy Way to Debug Passport Authentication in Express, Today I've got for you a quick and easy way to debug your Passport serializeUser(function (user, done) { done(null, user); }); // deserialize user When you start using Passport, you may encounter some problems with initial  Passport. Passport is Express-compatible authentication middleware for Node.js. Passport's sole purpose is to authenticate requests, which it does through an extensible set of plugins known as strategies. Passport does not mount routes or assume any particular database schema, which maximizes flexibility and allows application-level decisions to be made by the developer.

Passport serializeUser/deserializeUser never be called · Issue #67 , Bug or feature request Bug Feature request Description of feature (or steps to reproduce if bug) I'm trying to use the component but I couldn't  Passport is authentication middleware for Node. It is designed to serve a singular purpose: authenticate requests. When writing modules, encapsulation is a virtue, so Passport delegates all other functionality to the application. This separation of concerns keeps code clean and maintainable, and makes Passport extremely easy to integrate into

Passport authentication with JWTStrategy not working, Hello, I was trying to authenticate with passport JWTStrategy passport-oauth.js : const passport passport.serializeUser(function (user, done) { done(null, user.​_id); }); I think using lowercase jwt causes problems sometimes. Authenticate. Authenticating requests is as simple as calling passport.authenticate() and specifying which strategy to employ. authenticate() 's function signature is standard Connect middleware, which makes it convenient to use as route middleware in Express applications.

Some quick tips for Passport, LoopBack supports Passport too, but when I first looked at it, I realized that I knew nothing passport.serializeUser(function(user, cb) { cb(null,  It shouldn't change for a simple reason: your User model should not change between different local strategies. The serializeUser / deserializeUser methods are here to link passport to your data models (user ID <=> data store relationship) whereas strategies are logic flows defining different ways to handle authentication (credentials => user ID relationship).

Comments
  • are you sure User.user.findOne() is the correct syntax to fetch user from database in deserialze method? shouldn't it be like this User.findOne()?
  • Ah, I was having issues with including the generateHash, and validPassword functions as part of the user model, to solve it I'm exporting the user model (User.user) and 2 functions from the User model file.
  • don't understand what you are doing exactly. if possible, share your user model file here
  • I've updated, to include the User model
  • I've update my user.js model to include validPassword and gernerateHash as part instance methods, however I was unable to do it in the way shown in the link, I had to use user.prototpye.validPassword otherwise it would say it was not a function. I'm still not able to login successfully, I get redirected to a blank error page.