如何在 Express 中禁用单个路由的 CORS,而不重写所有路由?

iho*_*ald 3 javascript node.js cors express reactjs

TLDR:在示例中,我只是想让它/users/delete不能被我的 React 应用程序之外的任何东西调用。

我的应用程序的后端 API 有很多使用 Express 的路由:

IE。服务器.js

app.get('/invoices/read', async (req, res) => {
    // gather data from db
    res.json({...data})
})
Run Code Online (Sandbox Code Playgroud)

我在全球范围内启用了 cors,如下所示:

服务器.js

app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header(
    'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept'
  );
  next();
});
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是,如何为这样的单个路由禁用 CORS

app.post('/users/delete', async (req, res) => {
    // delete user out of database
    res.sendStatus(200)
})
Run Code Online (Sandbox Code Playgroud)

无需将我的所有路线重写为如下所示:

var cors = require('cors');

app.get('/invoices/read', cors(), async (req, res) => {
    // gather data from db
    res.json({...data})
})
Run Code Online (Sandbox Code Playgroud)

这样用户就不能仅使用/users/delete任意 ID 发出 POST 请求来尝试从我的系统中删除用户?

我是否需要在标头中包含来源,还是需要为该路由禁用 CORS?

  • 过去,我在使用Access-Control-Allow-Origin标头获取一串来源字符串时遇到了困难。

Fel*_*van 10

仅在您想要“禁用”的路线上覆盖标头:

res.set('Access-Control-Allow-Origin', 'alloweddomain.com')
Run Code Online (Sandbox Code Playgroud)

如果您需要允许多个域,您可以列出允许的域并检查其中是否包含源:

const allowedDomains = ['allowedomain1.com', 'alloweddomain2.com'];
const origin = req.get('origin');

if (allowedDomains.includes(origin)) {
  res.set('Access-Control-Allow-Origin', origin);
}
Run Code Online (Sandbox Code Playgroud)


phs*_*rce 5

我发现的另一种解决方案:

在全局调用 时app.use(cors()),您可以添加选项preflightContinue: true,这应该允许特定页面上的后续中间件覆盖它。

在顶层配置中

  app.use(
    cors({
      origin: 'http://localhost:9001',
      // Allow follow-up middleware to override this CORS for options
      preflightContinue: true,
    }),
  );
Run Code Online (Sandbox Code Playgroud)

在我的具体路线声明中

router.options('/myRoute', cors(myRouteOptions));
router.post(
  '/myRoute',
  cors(myRouteOptions),
  async (req, res) => {
    // ...
  },
);
Run Code Online (Sandbox Code Playgroud)