Skip to content

Instantly share code, notes, and snippets.

@umidjons
Last active August 10, 2018 11:48
Show Gist options
  • Save umidjons/857013a6c8fbd1c99ada to your computer and use it in GitHub Desktop.
Save umidjons/857013a6c8fbd1c99ada to your computer and use it in GitHub Desktop.
Authenticate a Node.js API with JSON Web Tokens

Authenticate a Node.js API with JSON Web Tokens

Original article: https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens

Set up AngularJS toaster (backend NodeJS app)

mkdir au
cd au
vim package.json

package.json content:

{
	"name":"authapp",
	"main":"server.js"
}
npm install express body-parser morgan mongoose jsonwebtoken --save
mkdir app\models
vim app\models\user.js

user.js content:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports = mongoose.model('User', new Schema({
  name: String,
  password: String,
  admin: Boolean
}));

config.js content:

module.exports = {
  secret: 'SomeSecretString',
  database: 'mongodb://localhost:27017/au'
};
vim server.js

server.js content:

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var jwt = require('jsonwebtoken');
var config = require('./config');
var User = require('./app/models/user');

var port = process.env.PORT || 3000;
mongoose.connect(config.database);

app.set('superSecret',config.secret);

app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

app.use(morgan('dev'));

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 nick = new User({
    name: 'John Doe',
    password: '123',
    admin: true
  });

  // save the user
  nick.save(function(err){
    if(err) throw err;

    console.log('User saved successfully');
    res.json({success: true});
  });
});

var apiRoutes = express.Router();

apiRoutes.post('/authenticate',function(req,res){
  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){
      if(user.password != req.body.password){
		res.json({success:false,message:'Authentication failed! Invalid password.'});
      } else {
		var token = jwt.sign({name:user.name}, app.get('superSecret'),{ expiresInMinutes: 1440});
		res.json({
		  success: true,
		  message: 'Enjoy your token!',
		  token: token
		});
      }
    }
  });
});

apiRoutes.use(function(req,res,next){
  var token = req.body.token || req.query.token || req.headers['x-access-token'];
  if(token){
    jwt.verify(token, app.get('superSecret'), function(err,decoded){
      if(err){
		return res.json({success:false, message:'Failed to authenticate token.'});
      } else {
		req.decoded = decoded;
		next();
      }
    });
  } else {
    return res.status(403).send({
      success: false,
      message: 'No token provided.'
    });
  }
});

apiRoutes.get('/',function(req,res){
  res.json({message: 'Welcome to the coolest API on earth!'});
});

apiRoutes.get('/users',function(req,res){
  User.find({},function(err,users){
    res.json(users);
  });
});

app.use('/api', apiRoutes);

app.listen(port);

console.log('Magic happens at http://localhost:'+port);

Create user

http://localhost:3000/setup

Authenticate a user:

post request http://localhost:3000/api/authenticate
with body (x-www-form-urlencoded)
name=John Doe
password=123

Save token from response:

{
  "success": true,
  "message": "Enjoy your token!",
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NjZhNWRmZWM0YTBmNWI4MWY3ZGUyN2EiLCJuYW1lIjoiSm9obiBEb2UiLCJwYXNzd29yZCI6IjEyMyIsImFkbWluIjp0cnVlLCJfX3YiOjB9.1lVy8FFahyEl1OBGHTNTn5c1r4xJZFgTsdJ-OsQpqvo"
}

Access protected areas with this token:

http://localhost:3000/api/
with header
x-access-token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NjZhNWRmZWM0YTBmNWI4MWY3ZGUyN2EiLCJuYW1lIjoiSm9obiBEb2UiLCJwYXNzd29yZCI6IjEyMyIsImFkbWluIjp0cnVlLCJfX3YiOjB9.1lVy8FFahyEl1OBGHTNTn5c1r4xJZFgTsdJ-OsQpqvo

OR
token query parameter
http://localhost:3000/api/users?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NjZhNWRmZWM0YTBmNWI4MWY3ZGUyN2EiLCJuYW1lIjoiSm9obiBEb2UiLCJwYXNzd29yZCI6IjEyMyIsImFkbWluIjp0cnVlLCJfX3YiOjB9.1lVy8FFahyEl1OBGHTNTn5c1r4xJZFgTsdJ-OsQpqvo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment