在单个路线上实施头盔CSP

我正在创build示例Express应用程序来演示Content-Security-Policy(CSP)头文件,并试图使用helmet-csp 。

所有helmet-csp的文档都显示它通过app.use(csp({ ... }))作为标准的第三方中间件 – 这将CSP头添加到我的应用程序中的每条path,但是我想要自定义它在个人路线上。

示例应用程序

 var express = require('express'); var http = require('http'); var csp = require('helmet-csp'); var app = express(); app.use(csp({ directives: { frameSrc: ["'none'"] } })); app.get('/', (request, response) => { response.send('hi, :wave: =]'); }); app.get('/frameable', (request, response) => { response.send('you can frame me!'); }); http.createServer(app).listen(80, (err) => { if (err) { return console.log('error', err); } }); 

如上所述, 每条路线都会收到CSP头文件:

内容安全策略:frame-src'none'

/frameable路线,我想重写这个CSP头是:

内容安全策略:frame-src'self'

每当我需要/想要定制头盔设置由头盔csp在每个路线的基础上,我是否需要手动覆盖它们在每个app.get中的一行,如:

 response.setHeader('Content-Security-Policy', "frame-src 'self'"); 

或者有没有办法通过helmet-csp来做到这一点?

自定义中间件能够改变标题,只需在use(csp)后添加use(csp)

 app.use(function (req, res, next) { if (req.url == '/frameable') { res.set('Content-Security-Policy', 'frame-src \'self\''); } next(); }); 

你也可以链接中间件,因为它是一个返回函数的函数:

 app.use(function (req, res, next) { var middleware; if (req.url == '/frameable') { middleware = csp({ directives: { frameSrc: ["'self'"] } }); } else { middleware = csp({ directives: { frameSrc: ["'none'"] } }); } middleware(req, res, next); }); 

此行为已内置到Express中。

Express允许您为每个路由指定多个请求处理程序。 由于csp返回一个路由处理器,你可以在你的路由处理器之前添加它:

 app.get('/frameable', csp({ directives: { frameSrc: ["'self'"] } }), (request, response) => { response.send('you can frame me!'); }); 

如果你喜欢把事情分开一点,你可以做这样的事情:

 var normalCspHandler = csp({ directives: { frameSrc: ["'none'"] } }); var frameSelfCspHandler = csp({ directives: { frameSrc: ["'self'"] } }); app.use(normalCspHandler); app.get('/frameable', frameSelfCspHandler, (request, response) => { response.send('you can frame me!'); }); 

(顺便说一句,我保持头盔,所以让我知道,如果你有任何反馈!)