Be the first user to complete this post
|
Add to List |
Setup passportjs for local authentication and authorization using expressjs
Packages
npm install --save passport passport-local passport-github connect-flash
npm install --save async
Passport Setup
Next, we will create a file where we configure passport to perform the authentication. In our case, I will be creating a config/passport.js file.
Lets setup the skeleton of this file
config/passport.js
var LocalStrategy = require('passport-local').Strategy,
async = require('async');
// Create a list of users just for demo.
// In reality, you will probably query a database
// to fetch this user
var users = {
'[email protected]': {
id: 'userOne',
password: 'one',
email: '[email protected]'
},
'[email protected]': {
id: 'userTwo',
password: 'two',
email: '[email protected]'
}
};
function createAccount (payload, callback) {
// Call API to create account
users[newUser.email] = newUser;
callback(null, newUser);
}
// Invokes callback with an error if email already exists, null otherwise
function findExistingEmail (email, callback) {
// Call API to check if the email already exists
if(users[email]) {
callback({err: 'Email Already Exists'});
} else {
callback(null, null);
}
}
module.exports = function (passport) {
// All our authentication code for signup and signin will go here
}
module.exports = function (passport) {
passport.serializeUser(function(user, done) {
// This is what passport will save in the session/cookie
done(null, user.email);
});
passport.deserializeUser(function(email, done) {
// Use the email saved in the session earlier
// to fetch the actual user
var user = users[email];
done(null, user);
});
}
SignIn
Lets add our first crucial function where we will perform the actual task of login.
config/passport.js
module.exports = function (passport) {
// ...
// We name our strategy 'local-login'.
// You can use any name you wish
// This is the name you will refer to later in a route
// that handles the login on client request
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
if(users[email] && users[email].password === password) {
return done(null, users[email]);
} else {
done(null, false, req.flash('message', 'Invalid email or password'));
}
}));
}
SignUp
Now, lets write some code that handles signup. For our case, I will use async to chain the function. We will first check if the email already exists. If not, asynch will proceed with invoking the function that creates an account.
config/passport.js
passport.use('local-signup',
new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // Pass back the entire request to the callback
}, function (req, email, password, done) {
process.nextTick(function() {
async.auto({
doesEmailAlreadyExist: function (cb, results) {
findExistingEmail(email, cb);
},
newAccount: ['doesEmailAlreadyExist',
function (cb, results) {
var newUser = {
email: email,
password: password
};
createAccount(newUser, cb);
}
]
}, function (err, results) {
if (err) {
done(null, false, req.flash('signupMessage', err.message));
} else {
done(null, results.newAccount);
}
});
});
})
);
Setup app.js
Add the following lines of code just below your first set of variable declarations.
app.js
// --- Authentication ---
var passport = require('passport'),
flash = require('connect-flash');
require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
// --------
app.use(session({
secret: config.session.SESSION_SECRET, // This can be any string
saveUninitialized: true,
resave: true
}));
var settings = {
config: config,
passport: passport
};
Route handlers
Now that we have everything in place, lets create simple route handlers for the login and signup actions.
In our routes folder, I will create a file called auth.js that will handle all the login actions. In the future, we will add route handlers for OAUTH based login strategies in the same file.
routes/auth.js
module.exports = function(app, settings){
var url = require('url'),
express = require('express'),
router = express.Router(),
passport = settings.passport;
router.post('/local-login', passport.authenticate('local-login', {
successRedirect : '/home.html',
failureRedirect : '/login.html',
failureFlash : true
}));
router.post('/local-signup', passport.authenticate('local-signup', {
successRedirect : '/home.html',
failureRedirect : '/signup.html',
failureFlash : true
}));
app.use('/auth',router);
};
// Divide all of your modules in different files and
// require them here
module.exports = function(app, settings){
require('./main')(app, settings);
require('./auth')(app, settings);
require('./home')(app, settings);
};
Also Read:
- set the default node version using nvm
- Organizing your expressjs routes in separate files.
- Scaling a basic nodejs application using clusters
- How to publish a package on npm
- Configuring jshint as a pre-commit hook for your nodejs applications