Created
March 9, 2017 03:59
-
-
Save sdesalas/a1d3c48d7233643fb1ca928f1ae38a0b to your computer and use it in GitHub Desktop.
Node JSON Web Token API authentication
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @see https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens | |
// ======================= | |
// get the packages we need ============ | |
// ======================= | |
var express = require('express'); | |
var app = express(); | |
var bodyParser = require('body-parser'); | |
var morgan = require('morgan'); | |
var mongoose = require('mongoose'); | |
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens | |
var config = require('./config'); // get our config file | |
var User = mongoose.model('User', new mongoose.Schema({ | |
name: String, | |
password: String, | |
admin: Boolean | |
})); // get our mongoose model | |
// ======================= | |
// configuration ========= | |
// ======================= | |
var port = process.env.PORT || 8080; // used to create, sign, and verify tokens | |
mongoose.connect('mongodb://<user>:<password>@olympia.modulusmongo.net:27017/<db>'); // connect to database | |
app.set('superSecret', 'jwtsalt123'); // secret variable | |
// use body parser so we can get info from POST and/or URL parameters | |
app.use(bodyParser.urlencoded({ extended: false })); | |
app.use(bodyParser.json()); | |
// use morgan to log requests to the console | |
app.use(morgan('dev')); | |
// ======================= | |
// routes ================ | |
// ======================= | |
// basic route | |
app.get('/', function(req, res) { | |
res.send('Hello! The API is at http://localhost:' + port + '/api'); | |
}); | |
app.get('/setup', function(req, res) { | |
// create a sample user | |
var sdesalas = new User({ | |
name: 'sdesalas', | |
password: 'password', | |
admin: true | |
}); | |
// save the sample user | |
sdesalas.save(function(err) { | |
if (err) throw err; | |
console.log('User saved successfully'); | |
res.json({ success: true }); | |
}); | |
}); | |
// API ROUTES ------------------- | |
// we'll get to these in a second | |
// get an instance of the router for api routes | |
var apiRoutes = express.Router(); | |
// TODO: route to authenticate a user (POST http://localhost:8080/api/authenticate) | |
apiRoutes.post('/authenticate', function(req, res) { | |
// find the user | |
User.findOne({ | |
name: req.body.name | |
}, function(err, user) { | |
if (err) throw err; | |
if (!user) { | |
res.json({ success: false, message: 'Authentication failed. User not found.' }); | |
} else if (user) { | |
// check if password matches | |
if (user.password != req.body.password) { | |
res.json({ success: false, message: 'Authentication failed. Wrong password.' }); | |
} else { | |
// if user is found and password is right | |
// create a token | |
var token = jwt.sign(user, app.get('superSecret'), { | |
expiresIn: 60*60*24 // expires in 24 hours | |
}); | |
// return the information including token as JSON | |
res.json({ | |
success: true, | |
message: 'Enjoy your token!', | |
token: token | |
}); | |
} | |
} | |
}); | |
}); | |
// TODO: route middleware to verify a token | |
apiRoutes.use(function(req, res, next) { | |
// check header or url parameters or post parameters for token | |
var token = req.body.token || req.query.token || req.headers['x-access-token']; | |
// decode token | |
if (token) { | |
// verifies secret and checks exp | |
jwt.verify(token, app.get('superSecret'), function(err, decoded) { | |
if (err) { | |
return res.json({ success: false, message: 'Failed to authenticate token.' }); | |
} else { | |
// if everything is good, save to request for use in other routes | |
req.decoded = decoded; | |
next(); | |
} | |
}); | |
} else { | |
// if there is no token | |
// return an error | |
return res.status(403).send({ | |
success: false, | |
message: 'No token provided.' | |
}); | |
} | |
}); | |
// route to show a random message (GET http://localhost:8080/api/) | |
apiRoutes.get('/', function(req, res) { | |
res.json({ message: 'Welcome to the coolest API on earth!' }); | |
}); | |
// route to return all users (GET http://localhost:8080/api/users) | |
apiRoutes.get('/users', function(req, res) { | |
User.find({}, function(err, users) { | |
res.json(users); | |
}); | |
}); | |
// apply the routes to our application with the prefix /api | |
app.use('/api', apiRoutes); | |
// ======================= | |
// start the server ====== | |
// ======================= | |
app.listen(port); | |
console.log('Magic happens at http://localhost:' + port); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Important => user version
[email protected]
and above due to vulerability in previous veresions.