【问题标题】:In REST API, How to restrict URL access from browser using Nodejs & Expressjs在 REST API 中,如何使用 Nodejs 和 Expressjs 限制浏览器的 URL 访问
【发布时间】:2021-08-19 02:25:35
【问题描述】:

我有一个 MEAN 堆栈应用程序并使用 Node.js 和 Express.js 作为后端 API。

假设我有如下的“cmets”路线

/* GET /comments listing. */
router.get("/", function(req, res, next) {
    Comment.find(function(err, comments) {
        if (err) return next(err);
        res.json(comments);
    });
});

并像这样在我的服务器中使用它:

var commentsRouter = require('./routes/comments');
...
app.use('/comments', commentsRouter);

我的问题是:有没有办法阻止用户在浏览器中访问 http://mrUrl/comments 并拒绝带有可能 403 Forbidden 消息的请求,但同时 JavaScript 文件尝试访问相同的 URL 会收到一条内容消息(在例子应该是res.json(comments);)

另外,是否有可能对所有路由启用一次这样的限制,而不是对每个路由启用。

【问题讨论】:

  • Javascript 将在浏览器上运行,因此您只能从浏览器获取请求。为了防止仅仅通过在地址栏中输入 url 在浏览器中获取结果,您需要将此请求作为 POST 请求。
  • “您需要将此请求作为 POST 请求发出”是什么意思?意思是?对于不同的模型,有几个具有不同 HTTp 动词的路由处理程序和中间件。我不太明白你的意思。
  • 像下面的例子,router.post('\',handler)。这样就无法从浏览器地址栏中获取数据。您还可以检查传入请求中的标头,以确保像下面由@Omer Shukar 提供的示例

标签: node.js rest api express


【解决方案1】:

是的,您可以使用middleware。

中间件是您可以在您正在执行的主函数之前或之后传递的函数(在本例中为GET comments)

函数位置的顺序很重要,先执行 - 先执行,然后您可以这样实现:

app.use(myBrowsingRestrictionMiddlewareFunction) // Runs 

app.use('/comments', commentsRouter);

app.use('/account', accountRouter);

您也可以在route handler 内使用:

app.post('/comments', myMakeSureDataIsAlrightFunction, myMainCreateCommentFunction, myAfterStatusWasSentToClientAndIWishToMakeAnotherInternalActionMiddleware);

属性req, res, next会自动传递到函数中。

这意味着,myBrowsingRestrictionMiddlewareFunction 接收它们,您可以像这样使用它们:

export function myBrowsingRestrictionMiddlewareFunction(req, res, next) {
  if (req.headers['my-special-header']) {
     // custom header exists, then call next() to pass to the next function
     next();

  } else {
  
    res.sendStatus(403);      

  }
}

编辑

扩展关于在FS结构中放置中间件的位置(个人建议):

我喜欢做的是像这样将路由器与 app.js 分开:

app.js

app.use('/', mainRouter);

router.js

const router = express.Router();

router.use(middlewareForAllRoutes);

router.use('/comments', commentsRouter);

router.use(middlewareForOnlyAnyRouteBelow);

router.use('/account', accountRouter);

router.use(middlewareThatWillBeFiredLast); // To activate this, remember to call next(); on the last function handler in your route.

cmetsRou​​ter.js

const router = express.Router();

router.use(middlewareForAllRoutesONLYFORWithinAccountRoute);

route.get('/', middlewareOnlyForGETAccountRoute, getAccountFunction);

router.post('/', createAccount);

【讨论】:

  • 使用中间件对我来说很有意义,但我不太了解您的路由处理程序方法。但是,会是“我的特殊标题”吗? myBrowsingRestrictionMiddlewareFunction 应该在哪里?可能在 app.js(server.js) 中?
  • 如果你的路由处理程序位于 app.js 中,那么是的,你将它放在 app.js 中,在路由处理程序本身之前。还在帖子中添加了我的方法
  • 什么是'my-special-header'?
  • 您可以调整您的客户端,为您发送到服务器的每个请求生成自定义标头。例如,在Angular 中,您可以使用HTTP Interceptor。但是您可以使用任何其他框架或纯 JS 来实现,将某个值的标头附加到 new XMLHttpRequest
  • 设置标头似乎是验证对服务器的请求的好方法。但是,在客户端中设置的标头是否可以被公众查看?例如使用“检查”元素?
猜你喜欢
  • 2015-03-15
  • 2015-02-24
  • 2015-05-06
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 2012-06-13
  • 2013-12-29
相关资源
最近更新 更多