Skip to content

Instantly share code, notes, and snippets.

@sdesalas
Created March 9, 2017 03:59
Show Gist options
  • Save sdesalas/a1d3c48d7233643fb1ca928f1ae38a0b to your computer and use it in GitHub Desktop.
Save sdesalas/a1d3c48d7233643fb1ca928f1ae38a0b to your computer and use it in GitHub Desktop.
Node JSON Web Token API authentication
// @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);
@sdesalas
Copy link
Author

sdesalas commented Mar 9, 2017

Important => user version jsonwebtoken@5.0.0 and above due to vulerability in previous veresions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment