I am trying to build a simple web token protected api in nodejs. I have been following this tutorial authenticate a node js api with json web tokens and have been implementing the steps in my app. I now have an api running that allows me to get/post/put/delete and a route that generates a webtoken for the user and shows it in plain text (for dev purposes). I am using node-restful for the api's but I am having some trouble understanding how I would actually verify if the client is sending the webtoken in their request, before allowing these get/post/put/delete requests.
Here is my router. Where I define the allowed requests:
const express = require('express')
const router = express.Router()
// Models - Load models here
var userModel = require('./models/User')
// Controllers - Load controllers here
const userController = require('./controllers/userController')
// Routes - Define routes here
router.post('api/authenticate', userController.authenticate) //Route that generates the webkey and shows it in the response
// Configure the endpoint that node-restful will expose. Here I want to first check if the user is sending his or her api key. Before allowing these methods.
userModel.methods(['get', 'put', 'post', 'delete'])
userModel.register(router, '/api/users')
// Export the router object
module.exports = router
Here is my userController where the token is generated.
// Dependencies
const User = require('../models/User')
const jwt = require('jsonwebtoken')
const config = require('../config.js')
module.exports = {
authenticate: function(req, res, next) {
// find the user
User.findOne({username: 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, config.secret, {
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
});
}
}
})
}
}
And here is my user model.
// Dependencies
const restful = require('node-restful')
const mongoose = restful.mongoose
// Schema
const userSchema = new mongoose.Schema({
username: String,
password: String,
email: String
})
// Return the model as a restful model to allow it being used as a route.
module.exports = restful.model('User', userSchema)
Is there some way I can protect these endpoints, using the same manner of syntax as I am currently using to expose them? I believe I would have to check for the web token before defining the methods:
userModel.methods(['get', 'put', 'post', 'delete'])
userModel.register(router, '/api/users')
If I simply remove the methods themselves, the user will not be able to get the page and is shown a: "Cannot GET /api/users" error. What if I wanted to show a custom error? For example: "No web token provided. Register to authenticate" etc etc? Any help is much appreciated. Thank you in advance.
via n0rd
No comments:
Post a Comment