修改动态请求加密,增加dockerfile部署文件
This commit is contained in:
parent
dd072c51cb
commit
cac8820983
@ -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 公钥与后端解密私钥对应 如更换需前后端一同更换
|
||||
|
@ -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
9
Dockerfile
Normal 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
29
default.conf
Normal 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;
|
||||
}
|
||||
}
|
@ -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
18
src/api/genKeyPair.ts
Normal 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);
|
||||
});
|
||||
}
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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
3
src/types/env.d.ts
vendored
@ -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 {
|
||||
|
@ -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); // 对数据进行加密
|
||||
};
|
||||
|
||||
// 解密
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user