Passport integration
Local authentication
Section titled “Local authentication”The passport-local module is used to implement a local authentication.
This module lets you authenticate using a username and password in your Node.js applications.
Registering the user :
const passport = require('passport');const LocalStrategy = require('passport-local').Strategy;
// A named strategy is used since two local strategy are used :// one for the registration and the other to sign-inpassport.use('localSignup', new LocalStrategy({ // Overriding defaults expected parameters, // which are 'username' and 'password' usernameField: 'email', passwordField: 'password', passReqToCallback: true // allows us to pass back the entire request to the callback .},function(req, email, password, next) { // Check in database if user is already registered findUserByEmail(email, function(user) { // If email already exists, abort registration process and // pass 'false' to the callback if (user) return next(null, false); // Else, we create the user else { // Password must be hashed ! let newUser = createUser(email, password);
newUser.save(function() { // Pass the user to the callback return next(null, newUser); }); } });});Logging in the user :
const passport = require('passport');const LocalStrategy = require('passport-local').Strategy;
passport.use('localSignin', new LocalStrategy({ usernameField : 'email', passwordField : 'password',},function(email, password, next) { // Find the user findUserByEmail(email, function(user) { // If user is not found, abort signing in process // Custom messages can be provided in the verify callback // to give the user more details concerning the failed authentication if (!user) return next(null, false, {message: 'This e-mail address is not associated with any account.'}); // Else, we check if password is valid else { // If password is not correct, abort signing in process if (!isPasswordValid(password)) return next(null, false); // Else, pass the user to callback else return next(null, user); } });});Creating routes :
// ...app.use(passport.initialize());app.use(passport.session());
// Sign-in route// Passport strategies are middlewaresapp.post('/login', passport.authenticate('localSignin', { successRedirect: '/me', failureRedirect: '/login'});
// Sign-up routeapp.post('/register', passport.authenticate('localSignup', { successRedirect: '/', failureRedirect: '/signup'});
// Call req.logout() to log outapp.get('/logout', function(req, res) { req.logout(); res.redirect('/');});
app.listen(3000);Getting started
Section titled “Getting started”Passport must be initialized using passport.initialize() middleware.
To use login sessions, passport.session() middleware is required.
Note that passport.serialize() and passport.deserializeUser() methods must be defined. Passport will serialize and deserialize user instances to and from the session
const express = require('express');const session = require('express-session');const passport = require('passport');const cookieParser = require('cookie-parser');const app = express();
// Required to read cookiesapp.use(cookieParser());
passport.serializeUser(function(user, next) { // Serialize the user in the session next(null, user);});
passport.deserializeUser(function(user, next) { // Use the previously serialized user next(null, user);});
// Configuring express-session middlewareapp.use(session({ secret: 'The cake is a lie', resave: true, saveUninitialized: true}));
// Initializing passportapp.use(passport.initialize());app.use(passport.session());
// Starting express server on port 3000app.listen(3000);Facebook authentication
Section titled “Facebook authentication”The passport-facebook module is used to implement a Facebook authentication. In this example, if the user does not exist on sign-in, he is created.
Implementing strategy :
const passport = require('passport');const FacebookStrategy = require('passport-facebook').Strategy;
// Strategy is named 'facebook' by defaultpassport.use({ clientID: 'yourclientid', clientSecret: 'yourclientsecret', callbackURL: '/auth/facebook/callback'},// Facebook will send a token and user's profilefunction(token, refreshToken, profile, next) { // Check in database if user is already registered findUserByFacebookId(profile.id, function(user) { // If user exists, returns his data to callback if (user) return next(null, user); // Else, we create the user else { let newUser = createUserFromFacebook(profile, token);
newUser.save(function() { // Pass the user to the callback return next(null, newUser); }); } });});Creating routes :
// ...app.use(passport.initialize());app.use(passport.session());
// Authentication routeapp.get('/auth/facebook', passport.authenticate('facebook', { // Ask Facebook for more permissions scope : 'email'}));
// Called after Facebook has authenticated the userapp.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect : '/me', failureRedirect : '/'}));
//...
app.listen(3000);Simple Username-Password Authentication
Section titled “Simple Username-Password Authentication”In your routes/index.js
Here user is the model for the userSchema
router.post('/login', function(req, res, next) { if (!req.body.username || !req.body.password) { return res.status(400).json({ message: 'Please fill out all fields' }); }
passport.authenticate('local', function(err, user, info) { if (err) { console.log("ERROR : " + err); return next(err); }
if(user) ( console.log("User Exists!") //All the data of the user can be accessed by user.x res.json({"success" : true}); return; } else { res.json({"success" : false}); console.log("Error" + errorResponse()); return; } })(req, res, next);});Google Passport authentication
Section titled “Google Passport authentication”We have simple module available in npm for goggle authetication name passport-google-oauth20
Consider the following example In this example have created a folder namely config having the passport.js and google.js file in the root directory. In your app.js include the following
var express = require('express');var session = require('express-session');var passport = require('./config/passport'); // path where the passport file placedvar app = express();passport(app);// other code to initailize the server , error handle
In the passport.js file in the config folder include the following code
var passport = require ('passport'),google = require('./google'),User = require('./../model/user'); // User is the mongoose model
module.exports = function(app){ app.use(passport.initialize()); app.use(passport.session()); passport.serializeUser(function(user, done){ done(null, user); }); passport.deserializeUser(function (user, done) { done(null, user); }); google();};In the google.js file in the same config folder include following
var passport = require('passport'),GoogleStrategy = require('passport-google-oauth20').Strategy,User = require('./../model/user');module.exports = function () {passport.use(new GoogleStrategy({ clientID: 'CLIENT ID', clientSecret: 'CLIENT SECRET', callbackURL: "http://localhost:3000/auth/google/callback" }, function(accessToken, refreshToken, profile, cb) { User.findOne({ googleId : profile.id }, function (err, user) { if(err){ return cb(err, false, {message : err}); }else { if (user != '' && user != null) { return cb(null, user, {message : "User "}); } else { var username = profile.displayName.split(' '); var userData = new User({ name : profile.displayName, username : username[0], password : username[0], facebookId : '', googleId : profile.id, }); // send email to user just in case required to send the newly created // credentails to user for future login without using google login userData.save(function (err, newuser) { if (err) { return cb(null, false, {message : err + " !!! Please try again"}); }else{ return cb(null, newuser); } }); } } }); } ));};Here in this example, if user is not in DB then creating a new user in DB for local reference using the field name googleId in user model.
Remarks
Section titled “Remarks”Password must always be hashed. A simple way to secure passwords using NodeJS would be to use bcrypt-nodejs module.