资讯动态

Nuxt2:打包后dist文件下变量的值不要明文显示 / 以base64值显示 / 起到一定的保护作用 / 增加逆向阅读成本

发布时间:2026/10/29 11:09:28 来源:尧图企业网站定制
一、需求描述前端项目 / nuxt2项目 打包后变量值为明文是没有混淆的内容这个状态是对的如果变量的值也混淆了就失去代码的意义了但是如何能在一定程度上“密文”显示呢 以增加逆向阅读成本。二、开发实现梳理feat(build): 在生产环境启用代码混淆保护- 引入 webpack-obfuscator 插件- 仅在生产环境启用代码字符串混淆和控制流扁平化- 注入死代码以增加反调试难度- 禁用 console 输出防止日志泄露- 字符串数组启用 base64 编码和随机旋转- 设置 75% 的字符串参与混淆处理三、优缺点分析用webpack-obfuscator对 api 这个单独的 js 文件做代码混淆不是普通 Terser 压缩可以控制字符串加密、控制流平坦化、变量名乱码。✅ 优点逆向阅读成本很高普通开发者打开混淆后的 js 看不懂❌ 缺点只会加密源码里的字符串浏览器发出请求后Network 面板依旧完整显示 url增加打包体积、页面解密耗时自动生成的 api 文件每次生成后都要参与混淆四、哪些内容会被混淆会被混淆不会被混淆变量名、函数名中文注释、文档字符串字符串字面量部分正则表达式内容控制流结构第三方库的固定文本对象属性名部分国际化/多语言文本五、webpack-obfuscator完整配置参数webpack-obfuscator是javascript-obfuscator的 Webpack 封装核心参数完全相同额外增加 Webpack 特有选项5.1、核心混淆参数继承自 javascript-obfuscator参数类型默认值说明compactbooleantrue压缩代码controlFlowFlatteningbooleanfalse控制流平坦化controlFlowFlatteningThresholdnumber0.75控制流平坦化概率deadCodeInjectionbooleanfalse注入死代码deadCodeInjectionThresholdnumber0.4死代码注入概率stringArraybooleantrue启用字符串数组stringArrayThresholdnumber0.75字符串加密概率stringArrayEncodingstring[][]编码base64,rc4identifierNamesGeneratorstringhexadecimal命名方式renameGlobalsbooleanfalse混淆全局变量debugProtectionbooleanfalse调试保护selfDefendingbooleanfalse自我保护disableConsoleOutputbooleanfalse禁用 consoledomainLockstring[][]域名锁定reservedNamesstring[][]保留标识符reservedStringsstring[][]保留字符串5.2、Webpack 特有参数参数类型默认值说明excludestring[][]排除不混淆的 chunk 文件名includestring[][]只混淆指定的 chunksourceMapbooleanfalse是否生成 sourceMapsourceMapModestringseparatesourceMap 模式sourceMapSourcesModestringsources-contentsourceMap 来源六、nuxt.config.js代码核心片段项目环境Nuxt2Webpack4// 安装依赖 yarn add -D webpack-obfuscator2.6.0 yarn add -D javascript-obfuscator2.19.1 obfuscator 的语义是混淆器 obfuscate动词使模糊、使晦涩难懂 obfuscator名词执行混淆操作的程序/工具 在代码安全领域代码混淆器的作用是 将可读的源代码转换为功能相同但难以阅读和理解的形式 增加逆向工程的难度 保护知识产权和商业逻辑require(events).EventEmitter.defaultMaxListeners 50 const path require(path) // 尝试加载 webpack-obfuscator未安装时不影响打包 let WebpackObfuscator null try { WebpackObfuscator require(webpack-obfuscator) } catch (e) { console.warn([webpack-obfuscator] 未安装跳过代码混淆) } const {env} process const isProd env.MODE prod let envFileName if ([DEV, TEST, UAT, PRE, PRD].indexOf(env.MODE) -1) { require(dotenv).config({ path: .env.${env.MODE} }) envFileName .env.${env.MODE} } else { require(dotenv).config() envFileName .env } const apiServer process.env.API_SERVER const {processenvabcdef} process.env if (!isProd) { console.log( 当前本地环境变量值: \n apiServer: ${apiServer} ) } else { console.log(当前线上环境变量值: \n 公共地址 : ${process.env.PUBLIC_PATH}) } const config { env: { /abc-def/: processenvabcdef, }, } let axios { proxy: true, } // 如果生产指定apiServer, 则使用绝对路径请求api if (isProd apiServer) { axios { proxy: false, baseURL: apiServer, } } module.exports { // dir在前srcDir在后 dir: { assets: ../m-front-common/pc/assets, layouts: layouts, middleware: middleware, pages: pages, static: ../m-front-common/pc/static, store: store, }, srcDir: src/, ssr: false, env: { COOKIE_PATH: process.env.COOKIE_PATH || /, }, proxy: config.env, router: { base: process.env.ROUTER_BASE, middleware: [meta, auth], mode: hash, extendRoutes(routes, resolve) { if (!(process.env.NODE_ENV prodution) process.argv.slice(2).includes(--list)) { require(./m-front-common/extendRoutes).extendRoutes(routes, resolve) } }, }, server: { port: 3001, host: localhost, }, /* ** Build configuration */ styleResources: { less: ../m-front-common/pc/assets/m-var.less, }, build: { publicPath: process.env.PUBLIC_PATH, extractCSS: isProd, extend (config, {isDev}) { config.resolve.alias config.resolve.alias || {} const {alias} config.resolve alias[api] path.join(__dirname, m-front-common/pc/api) alias.vue path.join(__dirname, node_modules/vue) // 生产环境通过 loader 方式对 src 目录下的 JS 进行混淆字符串 base64 加密 if (!isDev WebpackObfuscator) { config.module.rules.push({ test: /\.js$/, include: [ path.resolve(__dirname, src), path.resolve(__dirname, m-front-common/pc/api), path.resolve(__dirname, m-front-common/pc/const), ], exclude: /node_modules/, enforce: post, use: { loader: WebpackObfuscator.loader, options: { stringArray: true, stringArrayEncoding: [base64], rotateStringArray: true, stringArrayThreshold: 1, // 关闭最耗时的选项避免打包卡住 controlFlowFlattening: false, deadCodeInjection: false, debugProtection: false, disableConsoleOutput: true, }, }, }) } // WebpackObfuscator }, }, /* ** Headers of the page */ head: { title: , meta: [{ charset: utf-8 }, { name: viewport, content: widthdevice-width, initial-scale1 }, { http-equiv: x-ua-compatible, content: IEedge, chrome1 }, { hid: description, name: description, content: , }, ], script: [], }, loading: { color: #5D81F9, }, css: [{ src: ../m-front-common/pc/assets/m-reset.less, lang: less, },], plugins: [], modules: [], axios, }七、打包后实现预期

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑