聊天数据加密
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import config from "@/config.js"
|
import config from "@/config.js"
|
||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
|
import { sm4Encrypt, sm4Decrypt } from '@/utils/crypto';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param url String,请求的地址,默认:none
|
* @param url String,请求的地址,默认:none
|
||||||
@@ -25,6 +26,14 @@ function StreamRequestMiniProgram(url, data = {}, onDataReceived, onError, onCom
|
|||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const Authorization = userStore.token ? encodeURIComponent(userStore.token) : '';
|
const Authorization = userStore.token ? encodeURIComponent(userStore.token) : '';
|
||||||
|
|
||||||
|
const requestBody = data && Object.keys(data).length > 0
|
||||||
|
? {
|
||||||
|
encrypted: true,
|
||||||
|
encryptedData: sm4Encrypt(config.sm4Config.key, JSON.stringify(data)),
|
||||||
|
timestamp: Date.now(),
|
||||||
|
}
|
||||||
|
: data;
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let buffer = '';
|
let buffer = '';
|
||||||
let hasReceivedContent = false;
|
let hasReceivedContent = false;
|
||||||
@@ -32,7 +41,7 @@ function StreamRequestMiniProgram(url, data = {}, onDataReceived, onError, onCom
|
|||||||
const requestTask = uni.request({
|
const requestTask = uni.request({
|
||||||
url: config.StreamBaseURl + url,
|
url: config.StreamBaseURl + url,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: data,
|
data: requestBody,
|
||||||
header: {
|
header: {
|
||||||
"Authorization": Authorization,
|
"Authorization": Authorization,
|
||||||
"Accept": "text/event-stream",
|
"Accept": "text/event-stream",
|
||||||
@@ -179,9 +188,20 @@ function StreamRequestMiniProgram(url, data = {}, onDataReceived, onError, onCom
|
|||||||
|
|
||||||
if (jsonData && jsonData.trim()) {
|
if (jsonData && jsonData.trim()) {
|
||||||
try {
|
try {
|
||||||
const parsedData = JSON.parse(jsonData);
|
let parsedData = JSON.parse(jsonData);
|
||||||
console.log('🔧 解析后的JSON:', parsedData);
|
console.log('🔧 解析后的JSON:', parsedData);
|
||||||
|
|
||||||
|
if (parsedData?.encrypted && typeof parsedData?.encryptedData === 'string') {
|
||||||
|
const decryptedStr = sm4Decrypt(config.sm4Config.key, parsedData.encryptedData);
|
||||||
|
if (decryptedStr && decryptedStr !== parsedData.encryptedData) {
|
||||||
|
try {
|
||||||
|
parsedData = JSON.parse(decryptedStr);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('SSE解密数据JSON解析失败:', e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 检查是否有错误信息
|
// 检查是否有错误信息
|
||||||
const finishReason = parsedData?.choices?.[0]?.finish_reason;
|
const finishReason = parsedData?.choices?.[0]?.finish_reason;
|
||||||
if (finishReason === "error") {
|
if (finishReason === "error") {
|
||||||
@@ -279,12 +299,21 @@ function StreamRequestH5(url, data = {}, onDataReceived, onError, onComplete) {
|
|||||||
"Accept": "text/event-stream",
|
"Accept": "text/event-stream",
|
||||||
"Content-Type": "application/json;charset=UTF-8"
|
"Content-Type": "application/json;charset=UTF-8"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const requestBody = data && Object.keys(data).length > 0
|
||||||
|
? {
|
||||||
|
encrypted: true,
|
||||||
|
encryptedData: sm4Encrypt(config.sm4Config.key, JSON.stringify(data)),
|
||||||
|
timestamp: Date.now(),
|
||||||
|
}
|
||||||
|
: data;
|
||||||
|
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(config.StreamBaseURl + url, {
|
const response = await fetch(config.StreamBaseURl + url, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers,
|
headers,
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(requestBody)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@@ -347,9 +376,21 @@ function StreamRequestH5(url, data = {}, onDataReceived, onError, onComplete) {
|
|||||||
try {
|
try {
|
||||||
// 检查JSON数据是否完整
|
// 检查JSON数据是否完整
|
||||||
if (jsonData && jsonData.trim() && jsonData !== "[DONE]") {
|
if (jsonData && jsonData.trim() && jsonData !== "[DONE]") {
|
||||||
const parsedData = JSON.parse(jsonData);
|
let parsedData = JSON.parse(jsonData);
|
||||||
console.log('🔧 解析后的JSON:', parsedData);
|
console.log('🔧 解析后的JSON:', parsedData);
|
||||||
|
|
||||||
|
if (parsedData?.encrypted && typeof parsedData?.encryptedData === 'string') {
|
||||||
|
const decryptedStr = sm4Decrypt(config.sm4Config.key, parsedData.encryptedData);
|
||||||
|
if (decryptedStr && decryptedStr !== parsedData.encryptedData) {
|
||||||
|
try {
|
||||||
|
const decrypted = JSON.parse(decryptedStr);
|
||||||
|
parsedData = decrypted;
|
||||||
|
} catch (e) {
|
||||||
|
console.error('SSE解密数据JSON解析失败:', e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 检查是否有错误信息
|
// 检查是否有错误信息
|
||||||
const finishReason = parsedData?.choices?.[0]?.finish_reason;
|
const finishReason = parsedData?.choices?.[0]?.finish_reason;
|
||||||
if (finishReason === "error") {
|
if (finishReason === "error") {
|
||||||
@@ -458,9 +499,21 @@ function StreamRequestH5(url, data = {}, onDataReceived, onError, onComplete) {
|
|||||||
console.log('📄 提取的剩余JSON数据:', jsonData);
|
console.log('📄 提取的剩余JSON数据:', jsonData);
|
||||||
if (jsonData && jsonData !== "[DONE]") {
|
if (jsonData && jsonData !== "[DONE]") {
|
||||||
try {
|
try {
|
||||||
const parsedData = JSON.parse(jsonData);
|
let parsedData = JSON.parse(jsonData);
|
||||||
console.log('🔧 解析后的剩余JSON:', parsedData);
|
console.log('🔧 解析后的剩余JSON:', parsedData);
|
||||||
|
|
||||||
|
if (parsedData?.encrypted && typeof parsedData?.encryptedData === 'string') {
|
||||||
|
const decryptedStr = sm4Decrypt(config.sm4Config.key, parsedData.encryptedData);
|
||||||
|
if (decryptedStr && decryptedStr !== parsedData.encryptedData) {
|
||||||
|
try {
|
||||||
|
const decrypted = JSON.parse(decryptedStr);
|
||||||
|
parsedData = decrypted;
|
||||||
|
} catch (e) {
|
||||||
|
console.error('SSE解密数据JSON解析失败:', e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 检查是否有错误信息
|
// 检查是否有错误信息
|
||||||
const finishReason = parsedData?.choices?.[0]?.finish_reason;
|
const finishReason = parsedData?.choices?.[0]?.finish_reason;
|
||||||
if (finishReason === "error") {
|
if (finishReason === "error") {
|
||||||
@@ -573,33 +626,49 @@ export function chatRequest(url, data = {}, method = 'GET', loading = false, hea
|
|||||||
|
|
||||||
const header = headers || {};
|
const header = headers || {};
|
||||||
header["Authorization"] = encodeURIComponent(Authorization);
|
header["Authorization"] = encodeURIComponent(Authorization);
|
||||||
|
|
||||||
|
const isEncryptedMethod = method.toUpperCase() === 'POST' || method.toUpperCase() === 'PUT';
|
||||||
|
const requestData = isEncryptedMethod && data && Object.keys(data).length > 0
|
||||||
|
? {
|
||||||
|
encrypted: true,
|
||||||
|
encryptedData: sm4Encrypt(config.sm4Config.key, JSON.stringify(data)),
|
||||||
|
timestamp: Date.now(),
|
||||||
|
}
|
||||||
|
: data;
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
uni.request({
|
uni.request({
|
||||||
url: config.StreamBaseURl + url,
|
url: config.StreamBaseURl + url,
|
||||||
method: method,
|
method: method,
|
||||||
data: data,
|
data: requestData,
|
||||||
header,
|
header,
|
||||||
success: resData => {
|
success: resData => {
|
||||||
// 响应拦截
|
|
||||||
if (resData.statusCode === 200) {
|
if (resData.statusCode === 200) {
|
||||||
|
let responseData = resData.data;
|
||||||
|
try {
|
||||||
|
if (responseData?.encrypted) {
|
||||||
|
const decrypted = sm4Decrypt(config.sm4Config.key, responseData.encryptedData);
|
||||||
|
responseData = JSON.parse(decrypted);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[chatRequest] 解密失败:', e.message);
|
||||||
|
}
|
||||||
const {
|
const {
|
||||||
code,
|
code,
|
||||||
msg
|
msg
|
||||||
} = resData.data
|
} = responseData
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
resolve(resData.data)
|
resolve(responseData)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: msg || '请求失败',
|
title: msg || '请求失败',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
// 拒绝Promise并提供详细错误信息
|
|
||||||
const err = new Error(msg || '请求失败,服务器返回错误码: ' + code)
|
const err = new Error(msg || '请求失败,服务器返回错误码: ' + code)
|
||||||
err.error = resData
|
err.error = resData
|
||||||
reject(err)
|
reject(err)
|
||||||
} else {
|
} else {
|
||||||
// 处理非200状态码
|
|
||||||
const errorMsg = `请求失败,HTTP状态码: ${resData.statusCode}`
|
const errorMsg = `请求失败,HTTP状态码: ${resData.statusCode}`
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: errorMsg,
|
title: errorMsg,
|
||||||
|
|||||||
Reference in New Issue
Block a user