修改动态请求加密,增加dockerfile部署文件

This commit is contained in:
yuzl6 2024-04-08 22:28:24 +08:00
parent dd072c51cb
commit cac8820983
12 changed files with 176 additions and 47 deletions

View File

@ -21,6 +21,7 @@ VITE_APP_EASYRETRY_ADMIN = 'http://localhost:8800/easy-retry'
VITE_APP_PORT = 80
VITE_APP_ENCRYPT_HEADER = 'encrypt-key'
# 接口加密功能开关(如需关闭 后端也必须对应关闭)
VITE_APP_ENCRYPT = true
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换

View File

@ -24,6 +24,7 @@ VITE_BUILD_COMPRESS = gzip
VITE_APP_PORT = 80
VITE_APP_ENCRYPT_HEADER = 'encrypt-key'
# 接口加密功能开关(如需关闭 后端也必须对应关闭)
VITE_APP_ENCRYPT = true
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换

9
Dockerfile Normal file
View File

@ -0,0 +1,9 @@
FROM nginx
MAINTAINER onesummer
RUN rm /etc/nginx/conf.d/default.conf
ADD default.conf /etc/nginx/conf.d/
COPY dist/ /usr/share/nginx/html/

29
default.conf Normal file
View File

@ -0,0 +1,29 @@
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location /prod-api/ {
proxy_pass http://172.16.0.151:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

View File

@ -28,6 +28,7 @@
"crypto-js": "4.2.0",
"echarts": "5.5.0",
"element-plus": "2.6.2",
"encryptlong": "^3.1.4",
"file-saver": "2.0.5",
"fuse.js": "7.0.0",
"image-conversion": "^2.1.1",

18
src/api/genKeyPair.ts Normal file
View File

@ -0,0 +1,18 @@
import request from '@/utils/request';
/**
*
* @param callback
*/
export function genKeyPair(callback: Function) {
return request({
url: '/genKeyPair',
headers: {
isToken: false,
repeatSubmit: false
},
method: 'get'
}).then((res) => {
return callback(res.data.uuidPrivateKey, res.data.RSA_PUBLIC_KEY);
});
}

View File

@ -2,9 +2,11 @@ import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { LoginData, LoginResult, VerifyCodeResult, TenantInfo } from './types';
import { UserInfo } from '@/api/system/user/types';
import { genKeyPair } from '@/api/genKeyPair';
// pc端固定客户端授权id
const clientId = import.meta.env.VITE_APP_CLIENT_ID;
const encryptHeader = import.meta.env.VITE_APP_ENCRYPT_HEADER;
/**
* @param data {LoginData}
@ -16,14 +18,26 @@ export function login(data: LoginData): AxiosPromise<LoginResult> {
clientId: data.clientId || clientId,
grantType: data.grantType || 'password'
};
return request({
url: '/auth/login',
headers: {
isToken: false,
isEncrypt: true
},
method: 'post',
data: params
return new Promise((resolve, reject) => {
genKeyPair((uuid, public_key) => {
request({
url: '/auth/login',
headers: {
isToken: false,
isEncrypt: true,
[encryptHeader]: uuid,
publicKey: public_key
},
method: 'post',
data: params
})
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
});
});
});
}
@ -34,14 +48,26 @@ export function register(data: any) {
clientId: clientId,
grantType: 'password'
};
return request({
url: '/auth/register',
headers: {
isToken: false,
isEncrypt: true
},
method: 'post',
data: params
return new Promise((resolve, reject) => {
genKeyPair((uuid, public_key) => {
request({
url: '/auth/register',
headers: {
isToken: false,
isEncrypt: true,
[encryptHeader]: uuid,
publicKey: public_key
},
method: 'post',
data: params
})
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
});
});
});
}

View File

@ -1,6 +1,8 @@
import request from '@/utils/request';
import { TenantForm, TenantQuery, TenantVO } from './types';
import { AxiosPromise } from 'axios';
import { genKeyPair } from '@/api/genKeyPair';
const encryptHeader = import.meta.env.VITE_APP_ENCRYPT_HEADER;
// 查询租户列表
export function listTenant(query: TenantQuery): AxiosPromise<TenantVO[]> {
@ -21,13 +23,25 @@ export function getTenant(tenantId: string | number): AxiosPromise<TenantVO> {
// 新增租户
export function addTenant(data: TenantForm) {
return request({
url: '/system/tenant',
method: 'post',
headers: {
isEncrypt: true
},
data: data
return new Promise((resolve, reject) => {
genKeyPair((uuid, public_key) => {
request({
url: '/system/tenant',
method: 'post',
headers: {
isEncrypt: true,
[encryptHeader]: uuid,
publicKey: public_key
},
data: data
})
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
});
});
});
}

View File

@ -4,6 +4,8 @@ import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { UserForm, UserQuery, UserVO, UserInfoVO } from './types';
import { parseStrEmpty } from '@/utils/ruoyi';
import { genKeyPair } from '@/api/genKeyPair';
const encryptHeader = import.meta.env.VITE_APP_ENCRYPT_HEADER;
/**
*
@ -72,13 +74,25 @@ export const resetUserPwd = (userId: string | number, version: number, password:
version,
password
};
return request({
url: '/system/user/resetPwd',
method: 'put',
headers: {
isEncrypt: true
},
data: data
return new Promise((resolve, reject) => {
genKeyPair((uuid, public_key) => {
request({
url: '/system/user/resetPwd',
method: 'put',
headers: {
isEncrypt: true,
[encryptHeader]: uuid,
publicKey: public_key
},
data: data
})
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
});
});
});
};
@ -132,13 +146,25 @@ export const updateUserPwd = (oldPassword: string, newPassword: string) => {
oldPassword,
newPassword
};
return request({
url: '/system/user/profile/updatePwd',
method: 'put',
headers: {
isEncrypt: true
},
data: data
return new Promise((resolve, reject) => {
genKeyPair((uuid, public_key) => {
request({
url: '/system/user/profile/updatePwd',
method: 'put',
headers: {
isEncrypt: true,
[encryptHeader]: uuid,
publicKey: public_key
},
data: data
})
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
});
});
});
};

3
src/types/env.d.ts vendored
View File

@ -14,10 +14,11 @@ interface ImportMetaEnv {
VITE_APP_MONITRO_ADMIN: string;
VITE_APP_POWERJOB_ADMIN: string;
VITE_APP_ENV: string;
VITE_APP_ENCRYPT: string
VITE_APP_ENCRYPT: string;
VITE_APP_RSA_PUBLIC_KEY: string;
VITE_APP_RSA_PRIVATE_KEY: string;
VITE_APP_CLIENT_ID: string;
VITE_APP_ENCRYPT_HEADER: string;
VITE_APP_WEBSOCKET: string;
}
interface ImportMeta {

View File

@ -1,16 +1,14 @@
import JSEncrypt from 'jsencrypt';
import JSEncrypt from 'encryptlong';
// 密钥对生成 http://web.chacuo.net/netrsakeypair
const publicKey = import.meta.env.VITE_APP_RSA_PUBLIC_KEY;
// 前端不建议存放私钥 不建议解密数据 因为都是透明的意义不大
const privateKey = import.meta.env.VITE_APP_RSA_PRIVATE_KEY;
// 加密
export const encrypt = (txt: string) => {
export const encrypt = (txt: string, publicKey: string) => {
const encryptor = new JSEncrypt();
encryptor.setPublicKey(publicKey); // 设置公钥
return encryptor.encrypt(txt); // 对数据进行加密
return encryptor.encryptLong(txt); // 对数据进行加密
};
// 解密

View File

@ -10,6 +10,7 @@ import FileSaver from 'file-saver';
import { getLanguage } from '@/lang';
import { encryptBase64, encryptWithAes, generateAesKey, decryptWithAes, decryptBase64 } from '@/utils/crypto';
import { encrypt, decrypt } from '@/utils/jsencrypt';
import { ElLoading, ElMessage, ElMessageBox, ElNotification } from 'element-plus';
const encryptHeader = 'encrypt-key';
let downloadLoadingInstance: LoadingInstance;
@ -79,10 +80,14 @@ service.interceptors.request.use(
if (import.meta.env.VITE_APP_ENCRYPT === 'true') {
// 当开启参数加密
if (isEncrypt && (config.method === 'post' || config.method === 'put')) {
// 生成一个 AES 密钥
const aesKey = generateAesKey();
config.headers[encryptHeader] = encrypt(encryptBase64(aesKey));
config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey);
// 根据 AES 密钥进行加密
const publicKey = (config.headers || {}).publicKey;
console.log('publicKey', publicKey);
config.data =
typeof config.data === 'object'
? encrypt(encodeURIComponent(JSON.stringify(config.data)), publicKey)
: encrypt(encodeURIComponent(config.data), publicKey);
delete config.headers['publicKey'];
}
}
// FormData数据去请求头Content-Type