I want to ignore some API URL of being checked against token authentication
I want to protect post and put methods but not get of this url
localhost:3000/api/events/
router.use(function(request, response) {
var token = request.body.token || request.query.token || request.headers['x-access-token'];
if (token) {
jwt.verify(token, app.get(superSecret), function(err, decoded) {
if (err)
return response.json({
sucess: false,
message: "Failed token Authentication"
});
else {
request.decoded = decoded;
next();
}
});
} else {
return response.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
How can I do this using jsonwebtoken in node,express
I want this to apply to only post,put,delete requests but not on get requests.
You can move your anonymous middleware to normal declared function and then pass it to all protected routes (you decide which route you want to protect!)
Your code could look like:
function tokenProtection(request, response, next) {
var token = request.body.token || request.query.token || request.headers['x-access-token'];
if (token) {
jwt.verify(token, app.get(superSecret), function(err, decoded) {
if (err)
return response.json({
sucess: false,
message: "Failed token Authentication"
});
else {
request.decoded = decoded;
next();
}
});
} else {
return response.status(403).send({
success: false,
message: 'No token provided.'
});
}
}
and now your routes could look like (your decision what you want to protect):
router.get('/item', function(req, res) { ... }); // not protected
router.get('/item/:id', function(req, res) { ... }); // not protected
router.post(tokenProtection,'/item', function(req, res) { ... });//protected
router.put(tokenProtection,'/item', function(req, res) { ... });//protected
router.get('/book', function(req, res) { ... });// not protected
router.get('/book/:id', function(req, res) { ... });// not protected
router.post(tokenProtection,'/book', function(req, res) { ... });//protected
router.put(tokenProtection,'/book', function(req, res) { ... });//protected
Put the routes you want to protect below your authentication route and the ones you do not want to protect can above the authentication route. Something like this,
// Require what will be needed
var express = require('express'),
User = require('../models/user'),
usersRouter = express.Router();
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = require('./config'); // get our config file
var secret = {superSecret: config.secret}; // secret variable,
// Create a new user and return as json for POST to '/api/users'
usersRouter.post('/', function (req, res) {
var user = new User(req.body);
user.save(function(){ //pre-save hook will be run before user gets saved. See user model.
res.json({user : user, message: "Thank You for Signing Up"});
});
});
usersRouter.post('/authentication_token', function(req, res){
var password = req.body.password;
// find the user
User.findOne({
email: req.body.email
}, function(err, user) {
//If error in finding the user throw the error
if (err) throw err;
//If there is no error and the user is not found.
if (!user) {
res.json({ success: false, message: 'Authentication failed. User not found.' });
//if the user is found
} else if (user) {
// check if password matches
user.authenticate(password, function(isMatch){
if(isMatch){
// if user is found and password is right
// create a token with full user object. This is fine because password is hashed. JWT are not encrypted only encoded.
var token = jwt.sign({email: user.email}, secret.superSecret, {
expiresIn: 144000
});
// set the user token in the database
user.token = token;
user.save(function(){
// return the information including token as JSON
res.json({
success: true,
id: user._id,
message: 'Enjoy your token!',
token: token
});
});
} else {
res.json({ success: false, message: 'Authentication failed. Wrong password.' });
}
});
}
});
});
//***********************AUTHENTICATED ROUTES FOR USERS******************************
// Return ALL the users as json to GET to '/api/users'
usersRouter.get('/', function (req, res) {
User.find({}, function (err, users) {
res.json(users);
});
});
// Export the controller
module.exports = usersRouter;
I actually explained this yesterday itself on my blog because I was struggling to figure it out. If you are still not clear, you can check it out here, Node API Authentication with JSON Web Tokens - the right way.
If there are other resources like in my case it was plans. Below is the code I put above all the routes for plans I wanted to authenticate.
// route middleware to verify a token. This code will be put in routes before the route code is executed.
PlansController.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'];
// If token is there, then decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, secret.superSecret, function(err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
// if everything is good, save to incoming 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.'
});
}
});
//***********************AUTHENTICATED ROUTES FOR PLAN BELOW******************************
PlansController.get('/', function(req, res){
Plan.find({}, function(err, plans){
res.json(plans);
});
});