var express = require('express');
var app = express();
var port = process.env.PORT || 3112;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
require('./config/passport')(passport);
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser.urlencoded({extended: false})); // get information from html forms
app.set('view engine', 'ejs');
app.use(session({resave: false, saveUninitialized: true, secret: 'secretsession' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash());
require('./app/routes.js')(app, passport); // load our routes and pass in our app and fully configured passport
app.listen(port);
console.log('Server running on ' + port);
{
"name": "nodepassport",
"version": "1.0.0",
"description": "This is a sample project to learn nodejs with passport authentication",
"main": "server.js",
"scripts": {
"test": "node server.js"
},
"repository": {
"type": "git",
"url": "null"
},
"keywords": [
"passport",
"node",
"google"
],
"author": "Kunal Gaurav",
"license": "ISC",
"dependencies": {
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.15.2",
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.3",
"ejs": "^2.5.2",
"express": "^4.14.0",
"express-session": "^1.14.1",
"method-override": "^2.3.6",
"mongoose": "^4.6.5",
"morgan": "^1.7.0",
"passport": "^0.3.2",
"passport-google-oauth2": "^0.1.6",
"passport-local": "^1.0.0"
}
}
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
phone : Number,
address : String
},
google : {
id : String,
token : String,
email : String,
name : String
}
});
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
module.exports = mongoose.model('User', userSchema);
module.exports = function(app, passport){
app.get('/', function(req,res){
res.render('index.ejs');
});
app.get('/login', function(req, res){
res.render('login.ejs', {message: req.flash('loginMessage')});
});
app.post('/login', passport.authenticate('local-login', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/login', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
app.get('/signup', function(req,res){
res.render('signup.ejs', {message: req.flash('signupMessage')});
});
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/profile',
failureFlash : true,
failureRedirect : '/signup'
}));
app.get('/profile', isLoggedIn, function(req, res){
res.render('profile.ejs', {
user: req.user
});
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
app.get('/auth/google', passport.authenticate('google', { scope : ['profile', 'email'] }));
// the callback after google has authenticated the user
app.get('/oauth2callback',
passport.authenticate('google', {
successRedirect : '/profile',
failureRedirect : '/'
}));
};
function isLoggedIn(req, res, next){
if(req.isAuthenticated())
return next();
res.redirect('/');
}
module.exports = {
'googleAuth' : {
'clientId': '1076003005201-1ib841080rgknt40c2jiodtg951hrca8.apps.googleusercontent.com',
'clientSecret': '53f6RzdI2Ksg6y6Q525VUzUi',
'callbackUrl': 'http://127.0.0.1.nip.io:3112/oauth2callback'
}
};
module.exports = {
'url' : 'mongodb://localhost:27017/students'
};
var LocalStrategy = require('passport-local').Strategy;
var GoogleStrategy = require('passport-google-oauth2').Strategy;
var User = require('../app/models/users');
var configAuth = require('./auth');
module.exports = function(passport){
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(function(id, done){
User.findById(id, function(err, user){
done(err,user);
});
});
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
process.nextTick(function() {
User.findOne({'local.email': email}, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
var newUser = new User();
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
console.log(req.body.phone);
newUser.local.phone = req.body.phone;
newUser.local.address = req.body.address;
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
User.findOne({ 'local.email' : email }, function(err, user) {
if (err)
return done(err);
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.'));
if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, user);
});
}));
passport.use(new GoogleStrategy({
clientID : configAuth.googleAuth.clientId,
clientSecret : configAuth.googleAuth.clientSecret,
callbackURL : configAuth.googleAuth.callbackUrl,
passReqToCallback : true
},
function(request, accessToken, refreshToken, profile, done) {
// make the code asynchronous
// User.findOne won't fire until we have all our data back from Google
process.nextTick(function() {
// try to find the user based on their google id
User.findOne({ 'google.id' : profile.id }, function(err, user) {
if (err)
return done(err);
if (user) {
// if a user is found, log them in
return done(null, user);
} else {
// if the user isnt in our database, create a new user
var newUser = new User();
console.log(profile.id);
// set all of the relevant information
newUser.google.id = profile.id;
newUser.google.token = token;
newUser.google.name = profile.displayName;
newUser.google.email = profile.emails[0].value; // pull the first email
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
};
<!doctype html>
<html>
<head>
<title>Node Authentication</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome -->
<style>
body { padding-top:80px; }
</style>
</head>
<body>
<div class="container">
<div class="jumbotron text-center">
<h1><span class="fa fa-lock"></span> Node Authentication</h1>
<p>Login or Register with:</p>
<a href="/auth/google" class="btn btn-danger"><span class="fa fa-google-plus"></span> Google</a>
<a href="/login" class="btn btn-default"><span class="fa fa-user"></span> Local Login</a>
<a href="/signup" class="btn btn-default"><span class="fa fa-user"></span> Local Signup</a>
</div>
</div>
</body>
</html>
<!doctype html>
<html>
<head>
<title>Node Authentication</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome -->
<style>
body { padding-top:80px; }
</style>
</head>
<body>
<div class="container">
<div class="col-sm-6 col-sm-offset-3">
<h1><span class="fa fa-sign-in"></span> Login</h1>
<!-- show any messages that come back with authentication -->
<% if (message.length > 0) { %>
<div class="alert alert-danger"><%= message %></div>
<% } %>
<!-- LOGIN FORM -->
<form action="/login" method="post">
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
<hr>
<p>Need an account? <a href="/signup">Signup</a></p>
<p>Or go <a href="/">home</a>.</p>
</div>
</div>
</body>
</html>
<!doctype html>
<html>
<head>
<title>Node Authentication</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">
<style>
body { padding-top:80px; word-wrap:break-word; }
</style>
</head>
<body>
<div class="container">
<div class="page-header text-center">
<h1><span class="fa fa-anchor"></span> Profile Page</h1>
<a href="/logout" class="btn btn-default btn-sm">Logout</a>
</div>
<div class="row">
<!-- LOCAL INFORMATION -->
<div class="col-sm-6">
<div class="well">
<h3><span class="fa fa-user"></span> Local</h3>
<p>
<strong>id</strong>: <%= user._id %><br>
<strong>email</strong>: <%= user.local.email %><br>
<strong>password</strong>: <%= user.local.password %>
</p>
</div>
</div>
</div>
</div>
</body>
</html>
<!doctype html>
<html>
<head>
<title>Node Authentication</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome -->
<style>
body { padding-top:80px; }
</style>
</head>
<body>
<div class="container">
<div class="col-sm-6 col-sm-offset-3">
<h1><span class="fa fa-sign-in"></span> Signup</h1>
<!-- show any messages that come back with authentication -->
<% if (message.length > 0) { %>
<div class="alert alert-danger"><%= message %></div>
<% } %>
<!-- LOGIN FORM -->
<form action="/signup" method="post">
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password">
</div>
<div class="form-group">
<label>Phone</label>
<input type="number" class="form-control" name="phone">
</div>
<div class="form-group">
<label>Address</label>
<input type="text" class="form-control" name="address">
</div>
<button type="submit" class="btn btn-warning btn-lg">Signup</button>
</form>
<hr>
<p>Already have an account? <a href="/login">Login</a></p>
<p>Or go <a href="/">home</a>.</p>
</div>
</div>
</body>
</html>