Setting up Passport.js (REST API w/token auth) Example
- app.js
var express = require('express'),
app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
passport = require('passport'),
flash = require('connect-flash'),
morgan = require('morgan'),
cookieParser = require('cookie-parser'),
bodyParser = require('body-parser'),
session = require('express-session');
var users = require('./controllers/users');
mongoose.connect('mongo uri goes here');
app.use(morgan('dev'));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(session({ secret: 'your secret key' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
require('./config/passport')(passport);
app.post('/login', users.login);
app.post('/signup', users.create);
app.get('/user/search/id/:id', users.read);
app.get('/user/search/username/:username', users.readByUsername);
app.get('/user/profile', isLoggedIn, users.me);
app.post('/user/update', isLoggedIn, users.update);
app.delete('/user/delete', isLoggedIn, users.delete);
app.post('/logout', function(req, res) {
req.logout();
res.end('Logged out')
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.end('Not logged in');
}
app.listen(port);
console.log('Server running on port ' + port);
- controllers/users.js
var User = require('../models/user');
var passport = require('passport');
module.exports = {};
module.exports.create = function(req, res) {
if (!req.body.name || !req.body.username || !req.body.password || !req.body.email)
return res.status(400).end('Invalid input');
User.findOne({ username: req.body.username }, function(err, user) {
if (user) {
return res.status(400).end('User already exists');
} else {
var newUser = new User();
newUser.name = req.body.name;
newUser.username = req.body.username;
newUser.password = newUser.generateHash(req.body.password);
newUser.email = req.body.email;
newUser.desc = req.body.desc;
newUser.save();
res.writeHead(200, {"Content-Type": "application/json"});
newUser = newUser.toObject();
delete newUser.password;
res.end(JSON.stringify(newUser));
}
});
};
module.exports.login = function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err)
return next(err);
if(!user)
return res.status(400).json({SERVER_RESPONSE: 0, SERVER_MESSAGE: "Wrong Credentials"});
req.logIn(user, function(err) {
if (err)
return next(err);
if (!err)
return res.json({ SERVER_RESPONSE: 1, SERVER_MESSAGE: "Logged in!" });
});
})(req, res, next);
};
module.exports.read = function(req, res) {
User.findById(req.params.id, function(err, user) {
if (user) {
res.writeHead(200, {"Content-Type": "application/json"});
user = user.toObject();
delete user.password;
delete user.__v;
res.end(JSON.stringify(user));
} else {
return res.status(400).end('User not found');
}
});
};
module.exports.readByUsername = function(req, res) {
User.findOne({ username: req.params.username }, function(err, user) {
if (user) {
res.writeHead(200, {"Content-Type": "application/json"});
user = user.toObject();
delete user.password;
delete user.__v;
res.end(JSON.stringify(user));
} else {
return res.status(400).end('User not found');
}
});
};
module.exports.me = function(req, res) {
User.findOne({ username: req.user.username }, function(err, user) {
if (user) {
res.writeHead(200, {"Content-Type": "application/json"});
user = user.toObject();
delete user.password;
delete user.__v;
res.end(JSON.stringify(user));
} else {
return res.status(400).end('User not found');
}
});
};
module.exports.update = function(req, res) {
User.findById(req.user.id, function(err, user) {
if (user) {
if (user.username != req.user.username) {
return res.status(401).end('Modifying other user');
} else {
user.name = req.body.name ? req.body.name : user.name;
user.desc = req.body.dec ? req.body.desc : user.desc;
user.username = req.body.username ? req.body.username : user.username;
user.password = req.body.password ? user.generateHash(req.body.password) : user.password;
user.email = req.body.email ? req.body.email : user.email;
user.save();
res.writeHead(200, {"Content-Type": "application/json"});
user = user.toObject();
delete user.password;
res.end(JSON.stringify(user));
}
} else {
return res.status(400).end('User not found');
}
});
};
module.exports.delete = function(req, res) {
User.remove({_id: req.user.id}, function(err) {
res.end('Deleted')
});
};
- models/user.js
var mongoose = require('mongoose'); var bcrypt = require('bcrypt-nodejs'); var md5 = require('MD5'); var userSchema = mongoose.Schema({ name: String, desc: String, username: String, password: String, email: String, avatar: String }); userSchema.methods.generateHash = function(password) { return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); }; userSchema.methods.validPassword = function(password) { return bcrypt.compareSync(password, this.password); }; module.exports = mongoose.model('User', userSchema);
* config/passport.js
```javascript
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
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(new LocalStrategy(function(username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
};