简体   繁体   中英

Securing routes on Express and NodeJs

I'm looking the best way to "restrict" specific routes, I'm going to explain it with an example:

I have two users:

-user1 id:123

-user2 id:456

Client Side (Angular):

 //LOGGED AS USER 123 $http.post('www.domain.com/api/user/123') .then(function (data) { // here I should receive the data from user 123 }) 

The code above it's easy to do, but I want to rescrict this endpoint (from server side) only for user 123. If user 456 try to get that endpoint shoul be kicked. Example:

 //LOGGED AS USER 456 $http.post('www.domain.com/api/user/123') .then(function (data) { // should return error (forbidden resource) }) 

As you can see, if your are logged as user 456, you could get data from "api/user/123", but you could get from "api/user/456"

I want to solve this from server side

QUESTION:

What is the best way to do it with Node/Express/JWT ??

I would use a different URL design. Instead of having

www.domain.com/api/user/123

I would just have

www.domain.com/api/user

And discover the user ID from the authentication token or session ID that is sent with the request.

I have seen lots of authorization/security bugs that originate from specifying identities in URLs. If you think about it, it is essentially duplicating the user ID parameter since it appears once in the URL and once in the authentication token. That kind of duplication often leads to problems with authorisation logic getting out of sync with itself.

Create middleware/authorize.js

const fs = require('fs');
const jwt = require('jsonwebtoken');

module.exports = (req, res, next) => {
    console.log('in!');
    let key = fs.readFileSync('rsa_2048_pub.pem');
    // If you are using default HMAC key the line above would be something like this:        
    // let key = process.env.JWT_SECRET // nodemon.json file needed for this to work

    try{
        const token = req.headers.authorization.split(' ')[1]; //req.headers.token;
        console.log(token);
        var decoded = jwt.verify(token, key)
        console.log(decoded);

        // add validation code here...

        next();

    }catch(err){
      return res.status(401).json({error: err, message: 'Invalid token.'});
    }
};

In routes/users.js you will import your middleware and have something like this:

const User = require('../models/user')
const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const authorize = require('../middleware/authorize'); //import your middleware

// add your middleware call to your routes
router.route('/validate-token').get(authorize, function(req,res, next){
  console.log('out!');

  res.status(200).json({message: 'Valid token.'});
});

You can use your payload to store information like userId , admin : true/false to authorize access in your middleware.

For a more complete authorization handling i recommend also using an authorization package like CASL together with JWT strategy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM