Skip to content
Snippets Groups Projects
Commit b7d9e0bb authored by Markus Grigull's avatar Markus Grigull
Browse files

Add user authentication

User passwords are stored with bcrypt hash & salt.
The authentication token is stored in the 'x-access-token' header.
parent 234462a2
No related branches found
No related tags found
No related merge requests found
auth.js 0 → 100644
// include
var jwt = require('jsonwebtoken');
var config = require('./config');
module.exports = {
validateToken: function(req, res, next) {
// check for token
if (!req.headers['x-access-token']) {
return res.status(403).send({ success: false, message: 'No token provided' });
}
// verify token
jwt.verify(req.headers['x-access-token'], config.secret, function(err, decoded) {
if (err) {
return res.status(403).send({ success: false, message: 'Authentication failed' });
}
// save to request in other routes
req.decoded = decoded;
next();
});
}
}
......@@ -2,5 +2,6 @@ module.exports = {
'databaseName': 'VILLAS',
/*'databaseURL': 'mongodb://mongo:27017/',*/
'databaseURL': 'mongodb://192.168.99.100:27017/',
'port': 3000
'port': 3000,
'secret': 'longsecretislong'
}
// include
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var Schema = mongoose.Schema;
......@@ -10,4 +11,44 @@ var userSchema = new Schema({
adminLevel: { type: Number, default: 0 }
});
userSchema.methods.verifyPassword = function(password, callback) {
bcrypt.compare(password, this.password, function(err, isMatch) {
if (err) {
return callback(err);
}
callback(null, isMatch);
});
};
// execute before each user.save() call
userSchema.pre('save', function(callback) {
// save user to use in callback
var user = this;
// stop if password hasn't changed
if (!user.isModified('password')) {
return callback();
}
// hash the password
bcrypt.genSalt(5, function(err, salt) {
if (err) {
callback(err);
}
// generate hash from password and salt
bcrypt.hash(user.password, salt, null, function(err, hash) {
if (err) {
return callback(err);
}
// save the hashed password
user.password = hash;
callback();
});
});
});
module.exports = mongoose.model('User', userSchema);
......@@ -4,6 +4,11 @@
"private": true,
"main": "server.js",
"dependencies": {
"mongoose": "^4.5.1"
"express": "^4.14.0",
"mongoose": "^4.5.1",
"body-parser": "^1.15.2",
"morgan": "^1.7.0",
"jsonwebtoken": "^7.0.1",
"bcrypt-nodejs": "^0.0.3"
}
}
// include
var express = require('express');
var jwt = require('jsonwebtoken');
var User = require('../models/user');
var auth = require('../auth');
var config = require('../config');
// create router
var router = express.Router();
// all user routes need authentication
router.use('/users', auth.validateToken);
// routes
router.route('/users').get(function(req, res) {
// get all users
......@@ -67,7 +73,7 @@ router.route('/users/:id').get(function(req, res) {
});
router.route('/users/:id').delete(function(req, res) {
User.remove({ _id: req.params.id }, function(req, res) {
User.remove({ _id: req.params.id }, function(err) {
if (err) {
return res.send(err);
}
......@@ -76,4 +82,27 @@ router.route('/users/:id').delete(function(req, res) {
});
});
router.route('/authenticate').post(function(req, res) {
// get the user by the name
if (!req.body.username || !req.body.password) {
return res.status(401).send({ success: false, message: 'Invalid credentials' });
}
User.findOne({ username: req.body.username }, function(err, user) {
// handle errors and missing user
if (err) {
return res.send(err);
}
if (!user) {
return res.status(401).send({ success: false, message: 'Invalid credentials' });
}
// create authentication token
var token = jwt.sign(user, config.secret, {});
return res.send({ success: true, message: 'Authenticated', token: token});
});
});
module.exports = router;
......@@ -2,6 +2,7 @@
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var morgan = require('morgan');
// local include
var config = require('./config');
......@@ -16,6 +17,7 @@ var app = express();
// configure app
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(morgan('dev'));
// connect to database
mongoose.connect(config.databaseURL + config.databaseName);
......@@ -27,3 +29,13 @@ app.use('/api/v1', users);
app.listen(config.port, function() {
console.log('Express server listening on port ' + config.port);
});
var newUser = User({ username: 'admin', password: 'test' });
newUser.save(function(err) {
if (err) {
console.log(err);
return;
}
console.log('Created default admin user from config file');
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment