We were able to get a dynamic nonce by having webpack build our index page (e.g via HtmlWebpackPlugin) as a template then serving it dynamically. This way, you can set __webpack_nonce__
to an interpolation expression like <%=nonce%>
and the server view engine can sub in your dynamic nonce at page-load time. For example, if you're using express:
Webpack config:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
filename: __dirname + '/dist/index.ejs',
})
]
}
Webpack entry point (index.js):
__webpack_nonce__ = '<%=nonce%>';
Express app:
// Generate dynamic nonce on each request cycle
const uuid = require('node-uuid');
app.use((req, res, next) => {
res.locals.nonce = uuid.v4();
next();
});
app.set('view engine', 'ejs');
app.route('/').get((req, res, next) => {
res.render('path/to/index.ejs', { nonce: res.locals.nonce });
});
The injected <script>
tags will have the literal attribute nonce=<%=nonce%>
appended, which the server will then interpolate when serving your page.
Note that if you use a custom template with HtmlWebpackPlugin, you might want to set a different interpolation delimiter for ejs
otherwise Webpack will interpolate the nonce expression at build time instead of runtime.
Express app:
const ejs = require('ejs);
ejs.delimiter = '?'; // Means instead use __webpack_nonce__ = '<?=nonce?>'
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…