保护Node.js中的API路由

时间:2017-10-19 03:07:36

标签: javascript node.js mongodb angular

我的Node.js API中有一些路由将数据从MongoDB数据库发送到Angular 4前端。

示例:

Node.js route:

router.get('/api/articles', (req, res) => {
    Article.find({}, (err, articles) => {
        if(err) return res.status(500).send("Something went wrong");
        res.status(200).send(articles);
    });
});

Angular 4服务功能:

getArticles() {
    return this.http.get('http://localhost:3000/api/articles')
    .map(res => res.json()).subscribe(res => this.articles = res);
}

问题是,如何保护我的Node.js API路由免受浏览器访问?当我去http://localhost:3000/api/articles时,我可以用json格式看到我的所有文章。

4 个答案:

答案 0 :(得分:2)

这不是安全措施,只是一种过滤请求的方法。为了安全起见,使用其他机制,如JWT或类似机制。

如果角度应用程序由您控制,则发送一个特殊的标题,例如X-Requested-With:XMLHttpRequest(Chrome默认为AJAX调用发送它),然后在响应之前检查是否存在此标题。

如果您真的特别关注将端点暴露给特殊情况,请使用唯一标头X-Request-App: MyNgApp并对其进行过滤。

答案 1 :(得分:2)

除非您愿意实施某种身份验证,否则您无法做到 - 即您的角色用户需要登录api。

可以使它不那么方便。例如,只需将您的路由切换为接受POST请求而不是GET请求,就会阻止浏览器轻松查看。它仍然可以在开发工具或卷曲中看到。

或者,您可以使用在快速处理程序中查找的角度请求设置标题,但这似乎只是为了安全性的外观而做了很多工作。

答案 2 :(得分:0)

最佳方法是实现身份验证令牌系统。您可以从静态令牌开始(稍后您可以通过授权实现动态令牌)。

Token只是一个字符串,用于确保请求经过身份验证。

Node.js route:

router.get('/api/articles', (req, res) => {
    let token = url.parse(req.url,true).query.token;   //Parse GET param from URL
    if("mytoken" == token){         // Validate Token
       Article.find({}, (err, articles) => {
        if(err) return res.status(500).send("Something went wrong");
        res.status(200).send(articles);
       });
    }else {
       res.status(401).send("Error:Invalid Token"); //Send Error message
    }

});

Angular 4服务功能:

getArticles() {
    return this.http.get('http://localhost:3000/api/articles?token=mytoken') // Add token when making call
    .map(res => res.json()).subscribe(res => this.articles = res);
}

答案 3 :(得分:0)

使用 Express ,您可以使用路由处理程序来允许或拒绝对端点的访问。此方法由 Passport 身份验证中间件使用(顺便说一下,您可以使用此中间件)。

function isAccessGranted (req, res, next) {
  // Here your authorization logic (jwt, OAuth, custom connection logic...)
  if (!isGranted) return res.status(401).end()
  next()
}

router.get('/api/articles', isAccessGranted, (req, res) => {
  //...
})

或者让它对所有路线更通用:

app.use('*', isAccessGranted)