首页 > 解决方案 > 在 REST API 中,如何使用 Nodejs 和 Expressjs 限制浏览器的 URL 访问

问题描述

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

假设我有一个“评论”路线如下

/* 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);

此外,是否有可能对所有路线启用这种限制一次,而不是每条路线。

标签: node.jsrestapiexpress

解决方案


是的,您可以使用middleware.

中间件是您可以在您正在执行的主函数之前或之后传递的函数(在这种情况下,GET comments

函数位置的顺序很重要,先到先得 - 先执行,然后像这样实现它:

app.use(myBrowsingRestrictionMiddlewareFunction) // Runs 

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

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

您还可以在 a 中使用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 分开,如下所示:

应用程序.js

app.use('/', mainRouter);

路由器.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.

评论路由器.js

const router = express.Router();

router.use(middlewareForAllRoutesONLYFORWithinAccountRoute);

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

router.post('/', createAccount);

推荐阅读