commit
09a3c478ed
@ -21,6 +21,7 @@ VITE_APP_EASYRETRY_ADMIN = 'http://localhost:8800/easy-retry'
|
|||||||
|
|
||||||
VITE_APP_PORT = 80
|
VITE_APP_PORT = 80
|
||||||
|
|
||||||
|
VITE_APP_ENCRYPT_HEADER = 'encrypt-key'
|
||||||
# 接口加密功能开关(如需关闭 后端也必须对应关闭)
|
# 接口加密功能开关(如需关闭 后端也必须对应关闭)
|
||||||
VITE_APP_ENCRYPT = true
|
VITE_APP_ENCRYPT = true
|
||||||
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
||||||
|
@ -24,6 +24,7 @@ VITE_BUILD_COMPRESS = gzip
|
|||||||
|
|
||||||
VITE_APP_PORT = 80
|
VITE_APP_PORT = 80
|
||||||
|
|
||||||
|
VITE_APP_ENCRYPT_HEADER = 'encrypt-key'
|
||||||
# 接口加密功能开关(如需关闭 后端也必须对应关闭)
|
# 接口加密功能开关(如需关闭 后端也必须对应关闭)
|
||||||
VITE_APP_ENCRYPT = true
|
VITE_APP_ENCRYPT = true
|
||||||
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
# 接口加密传输 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",
|
"crypto-js": "4.2.0",
|
||||||
"echarts": "5.5.0",
|
"echarts": "5.5.0",
|
||||||
"element-plus": "2.6.2",
|
"element-plus": "2.6.2",
|
||||||
|
"encryptlong": "^3.1.4",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
"fuse.js": "7.0.0",
|
"fuse.js": "7.0.0",
|
||||||
"image-conversion": "^2.1.1",
|
"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 { AxiosPromise } from 'axios';
|
||||||
import { LoginData, LoginResult, VerifyCodeResult, TenantInfo } from './types';
|
import { LoginData, LoginResult, VerifyCodeResult, TenantInfo } from './types';
|
||||||
import { UserInfo } from '@/api/system/user/types';
|
import { UserInfo } from '@/api/system/user/types';
|
||||||
|
import { genKeyPair } from '@/api/genKeyPair';
|
||||||
|
|
||||||
// pc端固定客户端授权id
|
// pc端固定客户端授权id
|
||||||
const clientId = import.meta.env.VITE_APP_CLIENT_ID;
|
const clientId = import.meta.env.VITE_APP_CLIENT_ID;
|
||||||
|
const encryptHeader = import.meta.env.VITE_APP_ENCRYPT_HEADER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param data {LoginData}
|
* @param data {LoginData}
|
||||||
@ -16,14 +18,26 @@ export function login(data: LoginData): AxiosPromise<LoginResult> {
|
|||||||
clientId: data.clientId || clientId,
|
clientId: data.clientId || clientId,
|
||||||
grantType: data.grantType || 'password'
|
grantType: data.grantType || 'password'
|
||||||
};
|
};
|
||||||
return request({
|
return new Promise((resolve, reject) => {
|
||||||
|
genKeyPair((uuid, public_key) => {
|
||||||
|
request({
|
||||||
url: '/auth/login',
|
url: '/auth/login',
|
||||||
headers: {
|
headers: {
|
||||||
isToken: false,
|
isToken: false,
|
||||||
isEncrypt: true
|
isEncrypt: true,
|
||||||
|
[encryptHeader]: uuid,
|
||||||
|
publicKey: public_key
|
||||||
},
|
},
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: params
|
data: params
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,14 +48,26 @@ export function register(data: any) {
|
|||||||
clientId: clientId,
|
clientId: clientId,
|
||||||
grantType: 'password'
|
grantType: 'password'
|
||||||
};
|
};
|
||||||
return request({
|
return new Promise((resolve, reject) => {
|
||||||
|
genKeyPair((uuid, public_key) => {
|
||||||
|
request({
|
||||||
url: '/auth/register',
|
url: '/auth/register',
|
||||||
headers: {
|
headers: {
|
||||||
isToken: false,
|
isToken: false,
|
||||||
isEncrypt: true
|
isEncrypt: true,
|
||||||
|
[encryptHeader]: uuid,
|
||||||
|
publicKey: public_key
|
||||||
},
|
},
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: params
|
data: params
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
import { TenantForm, TenantQuery, TenantVO } from './types';
|
import { TenantForm, TenantQuery, TenantVO } from './types';
|
||||||
import { AxiosPromise } from 'axios';
|
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[]> {
|
export function listTenant(query: TenantQuery): AxiosPromise<TenantVO[]> {
|
||||||
@ -21,13 +23,25 @@ export function getTenant(tenantId: string | number): AxiosPromise<TenantVO> {
|
|||||||
|
|
||||||
// 新增租户
|
// 新增租户
|
||||||
export function addTenant(data: TenantForm) {
|
export function addTenant(data: TenantForm) {
|
||||||
return request({
|
return new Promise((resolve, reject) => {
|
||||||
|
genKeyPair((uuid, public_key) => {
|
||||||
|
request({
|
||||||
url: '/system/tenant',
|
url: '/system/tenant',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: {
|
headers: {
|
||||||
isEncrypt: true
|
isEncrypt: true,
|
||||||
|
[encryptHeader]: uuid,
|
||||||
|
publicKey: public_key
|
||||||
},
|
},
|
||||||
data: data
|
data: data
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import request from '@/utils/request';
|
|||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
import { UserForm, UserQuery, UserVO, UserInfoVO } from './types';
|
import { UserForm, UserQuery, UserVO, UserInfoVO } from './types';
|
||||||
import { parseStrEmpty } from '@/utils/ruoyi';
|
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,
|
version,
|
||||||
password
|
password
|
||||||
};
|
};
|
||||||
return request({
|
return new Promise((resolve, reject) => {
|
||||||
|
genKeyPair((uuid, public_key) => {
|
||||||
|
request({
|
||||||
url: '/system/user/resetPwd',
|
url: '/system/user/resetPwd',
|
||||||
method: 'put',
|
method: 'put',
|
||||||
headers: {
|
headers: {
|
||||||
isEncrypt: true
|
isEncrypt: true,
|
||||||
|
[encryptHeader]: uuid,
|
||||||
|
publicKey: public_key
|
||||||
},
|
},
|
||||||
data: data
|
data: data
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -132,13 +146,25 @@ export const updateUserPwd = (oldPassword: string, newPassword: string) => {
|
|||||||
oldPassword,
|
oldPassword,
|
||||||
newPassword
|
newPassword
|
||||||
};
|
};
|
||||||
return request({
|
return new Promise((resolve, reject) => {
|
||||||
|
genKeyPair((uuid, public_key) => {
|
||||||
|
request({
|
||||||
url: '/system/user/profile/updatePwd',
|
url: '/system/user/profile/updatePwd',
|
||||||
method: 'put',
|
method: 'put',
|
||||||
headers: {
|
headers: {
|
||||||
isEncrypt: true
|
isEncrypt: true,
|
||||||
|
[encryptHeader]: uuid,
|
||||||
|
publicKey: public_key
|
||||||
},
|
},
|
||||||
data: data
|
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_MONITRO_ADMIN: string;
|
||||||
VITE_APP_POWERJOB_ADMIN: string;
|
VITE_APP_POWERJOB_ADMIN: string;
|
||||||
VITE_APP_ENV: string;
|
VITE_APP_ENV: string;
|
||||||
VITE_APP_ENCRYPT: string
|
VITE_APP_ENCRYPT: string;
|
||||||
VITE_APP_RSA_PUBLIC_KEY: string;
|
VITE_APP_RSA_PUBLIC_KEY: string;
|
||||||
VITE_APP_RSA_PRIVATE_KEY: string;
|
VITE_APP_RSA_PRIVATE_KEY: string;
|
||||||
VITE_APP_CLIENT_ID: string;
|
VITE_APP_CLIENT_ID: string;
|
||||||
|
VITE_APP_ENCRYPT_HEADER: string;
|
||||||
VITE_APP_WEBSOCKET: string;
|
VITE_APP_WEBSOCKET: string;
|
||||||
}
|
}
|
||||||
interface ImportMeta {
|
interface ImportMeta {
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
import JSEncrypt from 'jsencrypt';
|
import JSEncrypt from 'encryptlong';
|
||||||
// 密钥对生成 http://web.chacuo.net/netrsakeypair
|
// 密钥对生成 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;
|
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();
|
const encryptor = new JSEncrypt();
|
||||||
encryptor.setPublicKey(publicKey); // 设置公钥
|
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 { getLanguage } from '@/lang';
|
||||||
import { encryptBase64, encryptWithAes, generateAesKey, decryptWithAes, decryptBase64 } from '@/utils/crypto';
|
import { encryptBase64, encryptWithAes, generateAesKey, decryptWithAes, decryptBase64 } from '@/utils/crypto';
|
||||||
import { encrypt, decrypt } from '@/utils/jsencrypt';
|
import { encrypt, decrypt } from '@/utils/jsencrypt';
|
||||||
|
import { ElLoading, ElMessage, ElMessageBox, ElNotification } from 'element-plus';
|
||||||
|
|
||||||
const encryptHeader = 'encrypt-key';
|
const encryptHeader = 'encrypt-key';
|
||||||
let downloadLoadingInstance: LoadingInstance;
|
let downloadLoadingInstance: LoadingInstance;
|
||||||
@ -79,10 +80,14 @@ service.interceptors.request.use(
|
|||||||
if (import.meta.env.VITE_APP_ENCRYPT === 'true') {
|
if (import.meta.env.VITE_APP_ENCRYPT === 'true') {
|
||||||
// 当开启参数加密
|
// 当开启参数加密
|
||||||
if (isEncrypt && (config.method === 'post' || config.method === 'put')) {
|
if (isEncrypt && (config.method === 'post' || config.method === 'put')) {
|
||||||
// 生成一个 AES 密钥
|
// 根据 AES 密钥进行加密
|
||||||
const aesKey = generateAesKey();
|
const publicKey = (config.headers || {}).publicKey;
|
||||||
config.headers[encryptHeader] = encrypt(encryptBase64(aesKey));
|
console.log('publicKey', publicKey);
|
||||||
config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey);
|
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
|
// FormData数据去请求头Content-Type
|
||||||
|
Loading…
Reference in New Issue
Block a user