姜臀臀 2024-04-19 12:06 采纳率: 0%
浏览 17
已结题

问题请教!vue项目关于Nginx配置nonce安全策略的问题

vue通过nginx部署,但是CSP安全策略不让设置‘unsafe-inline’,所以vue前端项目的script、style都无法执行,尝试了很多方法,请大家帮我。

我的nginx配置:


#user  nobody;
worker_processes  1;
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;    
    sendfile        on;
    keepalive_timeout  600000;
    client_max_body_size  10M;
    client_body_buffer_size 4M;
    
    server {
        listen      80;
                server_name  localhost;
                add_header X-Content-Type-Options "nosniff";
        add_header X-Frame-Options "SAMEORIGIN";
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        add_header Referrer-Policy "origin"; 
        add_header X-Download-Options "noopen";
        add_header X-Permitted-Cross-Domain-Policies "none";
        add_header Access-Control-Allow-Origin '192.168.200.128:80';
        server_tokens off;
        
        location / {
            sub_filter_once off;
            sub_filter NONCE_TOKEN $request_id;        
            add_header Content-Security-Policy "object-src 'self';script-src 'self' 'strict-dynamic' 'nonce-$request_id';style-src 'self' 'unsafe-inline'";
            if ($request_uri ~* \.(php|zip|arj|lzma|wim|war|ear|ar|gz|rac|tar|txt|arc|ARC)$) {
                return 403;
            }
            root   /home/dist;
            try_files $uri $uri/ /index.html;
            index  index.html index.htm;
        }

        location ~* \.(php|zip|arj|lzma|wim|war|ear|ar|gz|rac|tar|txt|arc|ARC)$ {    
             deny all;    
        } 
        location /prod-api/{
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://localhost:8080/;
            proxy_connect_timeout 600s;
            proxy_send_timeout 600s;
            proxy_read_timeout 600s;
        }

        error_page 401 403 404 500 502 503 504  /404;
        location = /404 {
            root   /home/dist;
        }
    }
}

我的vue.config.js配置:

'use strict'
const path = require('path')
const defaultSettings = require('./src/settings.js')
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");

function resolve(dir) {
  return path.join(__dirname, dir)
}

const name = defaultSettings.title || '系统' // 标题

const port = process.env.port || process.env.npm_config_port || 80 // 端口


module.exports = {
  publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
  // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
  outputDir: 'dist',
  // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
  assetsDir: 'static',
  // 是否开启eslint保存检测,有效值:ture | false | 'error'
  lintOnSave: process.env.NODE_ENV === 'development',
  // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
  productionSourceMap: false,
  // webpack-dev-server 相关配置
  devServer: {
    host: '0.0.0.0',
    port: port,
    proxy: {

      [process.env.VUE_APP_BASE_API]: {
        target: `http://localhost:8080`,
        changeOrigin: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_BASE_API]: ''
        }
      }
    },
    disableHostCheck: true
  },
  configureWebpack: {
    name: name,
    resolve: {
      alias: {
        '@': resolve('src')
      }
    },
    plugins: [
      new ScriptExtHtmlWebpackPlugin({
        custom: {
          //test: /runtime|app/,
          test: /(.*\.js)/, // adjust this regex based on your demand
          attribute: 'nonce',
          value:'<%= nonce %>'
        }
      })
    ]
  },
  chainWebpack(config) {
    config.plugins.delete('preload') // TODO: need test
    config.plugins.delete('prefetch') // TODO: need test
    config.module
      .rule('svg')
      .exclude.add(resolve('src/assets/icons'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/assets/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()

    // set preserveWhitespace
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.compilerOptions.preserveWhitespace = true
        return options
      })
      .end()

    config
      .when(process.env.NODE_ENV !== 'development',
        config => {
          config
            .plugin('ScriptExtHtmlWebpackPlugin')
            .after('html')
            .use('script-ext-html-webpack-plugin', [{
            // `runtime` must same as runtimeChunk name. default is `runtime`
              inline: /runtime\..*\.js$/
            }])
            .end()
          config
            .optimization.splitChunks({
              chunks: 'all',
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'initial' // only package third parties that are initially dependent
                },
                elementUI: {
                  name: 'chunk-elementUI', // split elementUI into a single package
                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
                },
                commons: {
                  name: 'chunk-commons',
                  test: resolve('src/components'), // can customize your rules
                  minChunks: 3, //  minimum common number
                  priority: 5,
                  reuseExistingChunk: true
                }
              }
            })
          config.optimization.runtimeChunk('single'),
          {
             from: path.resolve(__dirname, './public/robots.txt'),//防爬虫文件
             to:'./',//到根目录下
          }
        }
      )
  }
}


前端访问报错:

img

我应该怎样改?

  • 写回答

18条回答 默认 最新

  • 码农阿豪 Java领域优质创作者 2024-04-19 12:32
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    使用 productionSourceMap 选项来关闭它 productionSourceMap: false, // webpack-dev-server 相关配置 devServer: { host: 'localhost', port: 8080, proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true, pathRewrite: { '^/api': '' } } } }, configureWebpack: { // webpack 配置 name: name, // 支持IE11 entry: { pollyfill: [ '@babel/polyfill'] }, output: { filename: '[name].[hash].js' }, plugins: [ new ScriptExtHtmlWebpackPlugin({ inline: /runtime\..*\.js$/ }), ], } 针对这个问题,可以通过以下几种方案解决: 1.使用nonce 在CSP安全策略中设置nonce值,通过在script和style标签的nonce属性上设置该值,来保证安全的执行script和style。 例如,在nginx配置中添加以下内容: location / { add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'nonce-1234567890'; style-src 'self' 'unsafe-inline' 'nonce-1234567890';"; } 然后在vue中引用的script和style标签上添加nonce属性,例如: <style>/* your style code */</style> <script src="your-script.js"></script> 2.禁用unsafe-inline 在CSP安全策略中禁用unsafe-inline,这样可以让所有的script和style都不能使用inline方式。 例如,在nginx配置中修改Content-Security-Policy为: location / { add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'strict-dynamic'; style-src 'self';"; } 这样,所有的script和style都必须以外部文件的方式引入,inline方式的代码将会被禁用。 3.使用hash或chunkhash 在vue项目中使用hash或chunkhash来保证文件的唯一性,这样可以避免使用unsafe-inline。 例如,在vue.config.js配置中添加: module.exports = { // ... configureWebpack: { output: { filename: '[name].[chunkhash].js', chunkFilename: '[name].[chunkhash].js' } } } 这样,在打包生成的文件中,每个文件都会被赋予唯一的hash值或chunkhash值,从而保证安全。
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月24日
  • 修改了问题 4月19日
  • 创建了问题 4月19日

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么