diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index a6617bc6f..3e2aabbed 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -196,6 +196,16 @@ mybatis-encryptor: publicKey: privateKey: +# 数据加密 +request-encryptor: + # 是否开启加密 + enable: false + # AES 加密头标识 + headerFlag: AES + # 公私钥 非对称算法的公私钥 如:SM2,RSA + publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ== + privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= + # Swagger配置 swagger: info: diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Decrypt.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Decrypt.java new file mode 100644 index 000000000..5158e405e --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Decrypt.java @@ -0,0 +1,15 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 当标有当前注解的接口,接口穿参为加密字符串,进行解密后为dto对象, 不影响后续参数校验。 + * @author wdhcr + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Decrypt { +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/CryptoFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/CryptoFilter.java new file mode 100644 index 000000000..486d4e337 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/CryptoFilter.java @@ -0,0 +1,58 @@ +package com.ruoyi.common.filter; + +import com.ruoyi.common.encrypt.EncryptContext; +import com.ruoyi.common.encrypt.encryptor.RsaEncryptor; +import com.ruoyi.common.enums.AlgorithmType; +import com.ruoyi.common.utils.StringUtils; +import lombok.SneakyThrows; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; + +/** + * Crypto 过滤器 + * + * @author wdhcr + */ +public class CryptoFilter implements Filter { + + public static final String CRYPTO_PUBLIC_KEY = "publicKey"; + public static final String CRYPTO_PRIVATE_KEY = "privateKey"; + public static final String CRYPTO_HEADER_FLAG = "headerFlag"; + private RsaEncryptor rsaEncryptor; + private String headerFlag; + + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + EncryptContext encryptContext = new EncryptContext(); + encryptContext.setAlgorithm(AlgorithmType.RSA); + encryptContext.setPublicKey(filterConfig.getInitParameter(CryptoFilter.CRYPTO_PUBLIC_KEY)); + encryptContext.setPrivateKey(filterConfig.getInitParameter(CryptoFilter.CRYPTO_PRIVATE_KEY)); + headerFlag = filterConfig.getInitParameter(CryptoFilter.CRYPTO_HEADER_FLAG); + rsaEncryptor = new RsaEncryptor(encryptContext); + } + + @SneakyThrows + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { + ServletRequest requestWrapper = null; + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + if (StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE) + && (HttpMethod.PUT.matches(httpServletRequest.getMethod()) || HttpMethod.POST.matches(httpServletRequest.getMethod()))) { + requestWrapper = new DecryptRequestBodyWrapper(httpServletRequest, rsaEncryptor, headerFlag); + } + if (null == requestWrapper) { + chain.doFilter(request, response); + } else { + chain.doFilter(requestWrapper, response); + } + } + + @Override + public void destroy() { + + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/DecryptRequestBodyWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/DecryptRequestBodyWrapper.java new file mode 100644 index 000000000..5bb653b72 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/DecryptRequestBodyWrapper.java @@ -0,0 +1,106 @@ +package com.ruoyi.common.filter; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.io.IoUtil; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.encrypt.EncryptContext; +import com.ruoyi.common.encrypt.encryptor.AesEncryptor; +import com.ruoyi.common.encrypt.encryptor.RsaEncryptor; +import com.ruoyi.common.enums.AlgorithmType; +import com.ruoyi.common.enums.EncodeType; +import com.ruoyi.common.exception.base.BaseException; +import com.ruoyi.common.utils.StringUtils; +import org.springframework.http.MediaType; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +/** + * 解密请求参数工具类 + * + * @author wdhcr + */ +public class DecryptRequestBodyWrapper extends HttpServletRequestWrapper { + + private final byte[] body; + + public DecryptRequestBodyWrapper(HttpServletRequest request, RsaEncryptor rsaEncryptor, String headerFlag) throws IOException { + super(request); + String requestRsa = request.getHeader(headerFlag); + if (StringUtils.isEmpty(requestRsa)) { + throw new BaseException("加密AES的动态密码不能为空"); + } + String decryptAes = new String(Base64.decode(rsaEncryptor.decrypt(requestRsa))); + request.setCharacterEncoding(Constants.UTF8); + byte[] readBytes = IoUtil.readBytes(request.getInputStream(), false); + String requestBody = StringUtils.toEncodedString(readBytes, StandardCharsets.UTF_8); + EncryptContext encryptContext = new EncryptContext(); + encryptContext.setAlgorithm(AlgorithmType.AES); + encryptContext.setPassword(decryptAes); + encryptContext.setEncode(EncodeType.BASE64); + AesEncryptor aesEncryptor = new AesEncryptor(encryptContext); + String decryptBody = aesEncryptor.decrypt(requestBody); + body = decryptBody.getBytes(StandardCharsets.UTF_8); + } + + @Override + public BufferedReader getReader() { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + + @Override + public int getContentLength() { + return body.length; + } + + @Override + public long getContentLengthLong() { + return body.length; + } + + @Override + public String getContentType() { + return MediaType.APPLICATION_JSON_VALUE; + } + + + + @Override + public ServletInputStream getInputStream() { + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() { + @Override + public int read() { + return bais.read(); + } + + @Override + public int available() { + return body.length; + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + }; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java index 0770c2162..925aebf0f 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java @@ -1,9 +1,13 @@ package com.ruoyi.framework.config; +import cn.hutool.core.collection.CollectionUtil; +import com.ruoyi.common.filter.CryptoFilter; import com.ruoyi.common.filter.RepeatableFilter; import com.ruoyi.common.filter.XssFilter; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.config.properties.RequestEncryptProperties; import com.ruoyi.framework.config.properties.XssProperties; +import com.ruoyi.framework.handler.DecryptUrlHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -12,6 +16,7 @@ import org.springframework.context.annotation.Configuration; import javax.servlet.DispatcherType; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -25,6 +30,34 @@ public class FilterConfig { @Autowired private XssProperties xssProperties; + @Autowired + private RequestEncryptProperties requestEncryptProperties; + + @Autowired + private DecryptUrlHandler decryptUrlHandler; + + @Bean + public FilterRegistrationBean cryptoFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new CryptoFilter()); + List urls = decryptUrlHandler.getUrls(); + if (CollectionUtil.isNotEmpty(urls) || requestEncryptProperties.getEnable()) { + registration.setEnabled(true); + registration.addUrlPatterns(urls.toArray(new String[0])); + } else { + registration.setEnabled(false); + } + registration.setName("cryptoFilter"); + HashMap param = new HashMap<>(); + param.put(CryptoFilter.CRYPTO_PUBLIC_KEY, requestEncryptProperties.getPublicKey()); + param.put(CryptoFilter.CRYPTO_PRIVATE_KEY, requestEncryptProperties.getPrivateKey()); + param.put(CryptoFilter.CRYPTO_HEADER_FLAG, requestEncryptProperties.getHeaderFlag()); + registration.setInitParameters(param); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); + return registration; + } + @SuppressWarnings({"rawtypes", "unchecked"}) @Bean @ConditionalOnProperty(value = "xss.enabled", havingValue = "true") @@ -34,8 +67,8 @@ public class FilterConfig { registration.setFilter(new XssFilter()); registration.addUrlPatterns(StringUtils.split(xssProperties.getUrlPatterns(), StringUtils.SEPARATOR)); registration.setName("xssFilter"); - registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); - Map initParameters = new HashMap(); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE + 1); + Map initParameters = new HashMap<>(); initParameters.put("excludes", xssProperties.getExcludes()); registration.setInitParameters(initParameters); return registration; diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/RequestEncryptProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/RequestEncryptProperties.java new file mode 100644 index 000000000..05b6ce390 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/RequestEncryptProperties.java @@ -0,0 +1,36 @@ +package com.ruoyi.framework.config.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 请求加解密属性配置类 + * @author wdhcr + */ +@Data +@Component +@ConfigurationProperties(prefix = "request-encryptor") +public class RequestEncryptProperties { + + /** + * 加密开关 + */ + private Boolean enable; + + /** + * 头部标识 + */ + private String headerFlag; + + + /** + * 公钥 + */ + private String publicKey; + + /** + * 私钥 + */ + private String privateKey; +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/DecryptUrlHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/DecryptUrlHandler.java new file mode 100644 index 000000000..0c1064b16 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/handler/DecryptUrlHandler.java @@ -0,0 +1,56 @@ +package com.ruoyi.framework.handler; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ReUtil; +import com.ruoyi.common.annotation.Decrypt; +import lombok.Data; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.*; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * 获取需要解密的Url配置 + * + * @author wdhcr + */ +@Data +@Component +public class DecryptUrlHandler implements InitializingBean { + + private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}"); + + private List urls = new ArrayList<>(); + + @Autowired + private RequestMappingHandlerMapping requestMappingHandlerMapping; + + @Override + public void afterPropertiesSet() { + Set set = new HashSet<>(); + Map map = requestMappingHandlerMapping.getHandlerMethods(); + List requestMappingInfos = map.entrySet().stream().filter(item -> { + HandlerMethod method = item.getValue(); + Decrypt decrypt = method.getMethodAnnotation(Decrypt.class); + // 标有解密注解的并且是post 或者put 请求的handler + return decrypt != null && CollectionUtil.containsAny(item.getKey().getMethodsCondition().getMethods(), Arrays.asList(RequestMethod.PUT, RequestMethod.POST)); + }).map(Map.Entry::getKey).collect(Collectors.toList()); + requestMappingInfos.forEach(info -> { + // 获取注解上边的 path 替代 path variable 为 * + Optional.ofNullable(info.getPathPatternsCondition()) + .map(PathPatternsRequestCondition::getPatterns) + .orElseGet(HashSet::new) + .forEach(url -> set.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, "*"))); + }); + urls.addAll(set); + } + +} diff --git a/ruoyi-ui-vue3/.env.development b/ruoyi-ui-vue3/.env.development index ac4d2c13f..dd3b79499 100644 --- a/ruoyi-ui-vue3/.env.development +++ b/ruoyi-ui-vue3/.env.development @@ -10,6 +10,9 @@ VITE_APP_BASE_API = '/dev-api' # 应用访问路径 例如使用前缀 /admin/ VITE_APP_CONTEXT_PATH = '/' +# 请求接口是否加密 +VITE_APP_IS_ENCRYPT = false + # 监控地址 VITE_APP_MONITRO_ADMIN = 'http://localhost:9090/admin/applications' diff --git a/ruoyi-ui-vue3/.env.production b/ruoyi-ui-vue3/.env.production index 18bb273cb..3e5f09a41 100644 --- a/ruoyi-ui-vue3/.env.production +++ b/ruoyi-ui-vue3/.env.production @@ -7,6 +7,9 @@ VITE_APP_ENV = 'production' # 应用访问路径 例如使用前缀 /admin/ VITE_APP_CONTEXT_PATH = '/' +# 请求接口是否加密 +VITE_APP_IS_ENCRYPT = false + # 监控地址 VITE_APP_MONITRO_ADMIN = '/admin/applications' diff --git a/ruoyi-ui-vue3/package.json b/ruoyi-ui-vue3/package.json index ad36a4f76..286cb2194 100644 --- a/ruoyi-ui-vue3/package.json +++ b/ruoyi-ui-vue3/package.json @@ -33,6 +33,7 @@ "devDependencies": { "@vitejs/plugin-vue": "3.1.0", "@vue/compiler-sfc": "3.2.45", + "crypto-js": "^4.1.1", "sass": "1.56.1", "unplugin-auto-import": "0.11.4", "vite": "3.2.3", diff --git a/ruoyi-ui-vue3/src/utils/aes.js b/ruoyi-ui-vue3/src/utils/aes.js new file mode 100644 index 000000000..d06da6fbe --- /dev/null +++ b/ruoyi-ui-vue3/src/utils/aes.js @@ -0,0 +1,38 @@ +import CryptoJS from 'crypto-js'; + +/** + * 随机生成aes 密钥 + * @returns {string} + */ +export const generateAesKey = () => { + return CryptoJS.enc.Utf8.parse(generateRandomString()); +}; + + +/** + * 使用密钥对数据进行加密 + * @param message + * @param aesKey + * @returns {string} + */ +export const encryptWithAes = (message, aesKey) => { + const encrypted = CryptoJS.AES.encrypt(message, aesKey, { + "mode": CryptoJS.mode.ECB, + "padding": CryptoJS.pad.Pkcs7 + }); + return encrypted.toString(); +}; + +/** + * 随机生成32位的字符串 + * @returns {string} + */ +const generateRandomString = () => { + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result = ''; + const charactersLength = characters.length; + for (let i = 0; i < 32; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +}; diff --git a/ruoyi-ui-vue3/src/utils/request.js b/ruoyi-ui-vue3/src/utils/request.js index 1da35094e..7510b777f 100644 --- a/ruoyi-ui-vue3/src/utils/request.js +++ b/ruoyi-ui-vue3/src/utils/request.js @@ -6,6 +6,9 @@ import { tansParams, blobValidate } from '@/utils/ruoyi' import cache from '@/plugins/cache' import { saveAs } from 'file-saver' import useUserStore from '@/store/modules/user' +import {encryptWithAes, generateAesKey} from "@/utils/aes"; +import {encrypt} from "@/utils/jsencrypt"; +import CryptoJS from "crypto-js"; let downloadLoadingInstance; // 是否显示重新登录 @@ -28,6 +31,8 @@ service.interceptors.request.use(config => { const isToken = (config.headers || {}).isToken === false // 是否需要防止数据重复提交 const isRepeatSubmit = (config.headers || {}).repeatSubmit === false + // 是否需要加密 + const isEncrypt = (config.headers || {}).isEncrypt === true || import.meta.env.VITE_APP_IS_ENCRYPT === 'true' if (getToken() && !isToken) { config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 } @@ -61,6 +66,13 @@ service.interceptors.request.use(config => { } } } + // 当开启参数加密 + if (isEncrypt && (config.method === 'post' || config.method === 'put')) { + // 生成一个 AES 密钥 + const aesKey = generateAesKey(); + config.headers['AES'] = encrypt(aesKey.toString(CryptoJS.enc.Base64)); + config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey); + } return config }, error => { console.log(error) diff --git a/ruoyi-ui/.env.development b/ruoyi-ui/.env.development index c5457c9a6..06160f864 100644 --- a/ruoyi-ui/.env.development +++ b/ruoyi-ui/.env.development @@ -7,6 +7,9 @@ ENV = 'development' # 若依管理系统/开发环境 VUE_APP_BASE_API = '/dev-api' +# 请求接口是否加密 +VUE_APP_IS_ENCRYPT = false + # 应用访问路径 例如使用前缀 /admin/ VUE_APP_CONTEXT_PATH = '/' diff --git a/ruoyi-ui/.env.production b/ruoyi-ui/.env.production index 1d2cbae6a..d66332bf6 100644 --- a/ruoyi-ui/.env.production +++ b/ruoyi-ui/.env.production @@ -7,6 +7,9 @@ ENV = 'production' # 若依管理系统/生产环境 VUE_APP_BASE_API = '/prod-api' +# 请求接口是否加密 +VUE_APP_IS_ENCRYPT = false + # 应用访问路径 例如使用前缀 /admin/ VUE_APP_CONTEXT_PATH = '/' diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index 16924f395..2cef4f922 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -68,6 +68,7 @@ "chalk": "4.1.0", "compression-webpack-plugin": "5.0.2", "connect": "3.6.6", + "crypto-js": "^4.1.1", "eslint": "7.15.0", "eslint-plugin-vue": "7.2.0", "lint-staged": "10.5.3", diff --git a/ruoyi-ui/src/utils/aes.js b/ruoyi-ui/src/utils/aes.js new file mode 100644 index 000000000..d06da6fbe --- /dev/null +++ b/ruoyi-ui/src/utils/aes.js @@ -0,0 +1,38 @@ +import CryptoJS from 'crypto-js'; + +/** + * 随机生成aes 密钥 + * @returns {string} + */ +export const generateAesKey = () => { + return CryptoJS.enc.Utf8.parse(generateRandomString()); +}; + + +/** + * 使用密钥对数据进行加密 + * @param message + * @param aesKey + * @returns {string} + */ +export const encryptWithAes = (message, aesKey) => { + const encrypted = CryptoJS.AES.encrypt(message, aesKey, { + "mode": CryptoJS.mode.ECB, + "padding": CryptoJS.pad.Pkcs7 + }); + return encrypted.toString(); +}; + +/** + * 随机生成32位的字符串 + * @returns {string} + */ +const generateRandomString = () => { + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result = ''; + const charactersLength = characters.length; + for (let i = 0; i < 32; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +}; diff --git a/ruoyi-ui/src/utils/request.js b/ruoyi-ui/src/utils/request.js index 850685cd6..7949faa30 100644 --- a/ruoyi-ui/src/utils/request.js +++ b/ruoyi-ui/src/utils/request.js @@ -6,6 +6,9 @@ import errorCode from '@/utils/errorCode' import { tansParams, blobValidate } from "@/utils/ruoyi"; import cache from '@/plugins/cache' import { saveAs } from 'file-saver' +import {encryptWithAes, generateAesKey} from "@/utils/aes"; +import {encrypt} from "@/utils/jsencrypt"; +import CryptoJS from "crypto-js"; let downloadLoadingInstance; // 是否显示重新登录 @@ -28,9 +31,12 @@ service.interceptors.request.use(config => { const isToken = (config.headers || {}).isToken === false // 是否需要防止数据重复提交 const isRepeatSubmit = (config.headers || {}).repeatSubmit === false + // 是否需要加密 + const isEncrypt = (config.headers || {}).isEncrypt === true || process.env.VUE_APP_IS_ENCRYPT === 'true' if (getToken() && !isToken) { config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 } + // get请求映射params参数 if (config.method === 'get' && config.params) { let url = config.url + '?' + tansParams(config.params); @@ -61,6 +67,13 @@ service.interceptors.request.use(config => { } } } + // 当开启参数加密 + if (isEncrypt && (config.method === 'post' || config.method === 'put')) { + // 生成一个 AES 密钥 + const aesKey = generateAesKey(); + config.headers['AES'] = encrypt(aesKey.toString(CryptoJS.enc.Base64)); + config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey); + } return config }, error => { console.log(error)