alextanhongpin
alextanhongpin

Reputation: 655

How to make prevent unprivilege access to rest api url?

This is a question about node.js and restful api.

I created a ProductModel with mongoose.Schema and this is the route to read the list of products.

app.get('/api/products', function (req, res) {
    ProductModel.find(function (err, products) {
        if (!err) 
            res.json(products);
        else
            console.log(err);
    });
});

When I run this application on a local server and access the url *:3000/api/products I can see the list of json data. Had I ran the test on a real server, that means anyone who access the url can see the data too.

How can I actually hide the data from other users?

Upvotes: 1

Views: 3036

Answers (2)

deitch
deitch

Reputation: 14581

The previous answer definitely will work for a single URL or a simple user. If you are doing a full app with lots of users, and different authorization levels, you need a security framework.

I am the author of cansecurity https://github.com/deitch/cansecurity

With cansecurity, you could do it programmatically:

cs = require('cansecurity');
app.use(cansec.validate);

app.get('/api/products', cansec.restrictToLoggedIn, function(req, res) {...});
// or lots of other built in authorization restrictions
app.get('/api/products', cansec.restrictToRoles("admin"), function(req, res) {...});
app.get('/api/products', cansec.restrictToSelf, function(req, res) {...});

Or you can even declare all of your authorization paths in a json config file:

app.use(cansec.validate);
app.use(cansec.authorizer('./route-security.json'));

And then your config:

{
    "routes": [
      // [verb,path,default,[test params,] test condition]
        ["GET","/api/products",true,"user === 'xyz'"],
      // and lots of other options
        ["GET","/api/user/:user","user.roles.admin === true || user.id === req.param('user')"],
        ["GET","/api/user/:user",{"private":"true"},"user.roles.admin === true || user.id === req.param('user')"],
        ["PUT","/api/user/:user","user.roles.admin === true || user.id === req.param('user')"],
        ["GET","/api/user/:user/roles","user.roles.admin === true || user.id === req.param('user')"],
        ["PUT","/api/user/:user/roles","user.roles.admin === true"]
    ]   
}

Upvotes: 1

harryy000
harryy000

Reputation: 553

If your criteria is only a particular user can access it or only signed user can access it,then you can do it with a helper function like below.

app.get('/api/products', check_user, function(req, res) {
    ProductModel.find(function(err, products) {
        if (!err)
            res.json(products);
        else
            console.log(err);
    });
});

function check_user(req, res, next) {
    //if you are using sessions then you can get the current user with req.user
    if (req.user != 'xyz') return res.json('message': 'you dont have permissions to access this url');
    next(); //if it is xyz then call the next() iterator function that will take u to the final callback(productFind)
};

Upvotes: 1

Related Questions