Original article: https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens
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