v1.0.0
This commit is contained in:
53
src/utils/crypto.js
Normal file
53
src/utils/crypto.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import CryptoJS from 'crypto-js'
|
||||
|
||||
// AES CBC 加密,IV 拼接在密文前面,并进行 Base64 编码// AES CBC 加密,IV 拼接在密文前面,并进行 Base64 编码
|
||||
export function aesEncrypt(plainText, hexKey) {
|
||||
// 转换密钥为WordArray
|
||||
const key = CryptoJS.enc.Hex.parse(hexKey)
|
||||
|
||||
// 生成一个随机的IV
|
||||
const iv = generateRandomIV() // 生成 16 字节的随机 IV
|
||||
|
||||
// 加密
|
||||
const encrypted = CryptoJS.AES.encrypt(plainText, key, {
|
||||
iv,
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
})
|
||||
|
||||
// 拼接IV和密文,IV在前,密文在后,最后Base64编码
|
||||
const ivAndCipherText = iv.concat(encrypted.ciphertext)
|
||||
return CryptoJS.enc.Base64.stringify(ivAndCipherText)
|
||||
}
|
||||
|
||||
// AES CBC 解密,IV 在密文前面,并且 Base64 解码
|
||||
export function aesDecrypt(base64CipherText, hexKey) {
|
||||
// 转换密钥为WordArray
|
||||
const key = CryptoJS.enc.Hex.parse(hexKey)
|
||||
|
||||
// Base64解码并转换为WordArray
|
||||
const cipherParams = CryptoJS.enc.Base64.parse(base64CipherText)
|
||||
|
||||
// 提取 IV(前 16 字节)
|
||||
const iv = cipherParams.clone().words.slice(0, 4) // 16 字节的 IV 对应 4 个字(每个字 4 字节)
|
||||
|
||||
// 提取密文
|
||||
const cipherText = cipherParams.clone().words.slice(4) // 从第 4 个字开始到最后的密文
|
||||
|
||||
// 解密
|
||||
const decrypted = CryptoJS.AES.decrypt({ ciphertext: CryptoJS.lib.WordArray.create(cipherText) }, key, {
|
||||
iv: CryptoJS.lib.WordArray.create(iv),
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
})
|
||||
|
||||
// 返回解密后的明文
|
||||
return decrypted.toString(CryptoJS.enc.Utf8)
|
||||
}
|
||||
function generateRandomIV() {
|
||||
const iv = []
|
||||
for (let i = 0; i < 16; i++) { // 16 字节的 IV
|
||||
iv.push(Math.floor(Math.random() * 256)) // 0-255 的随机数
|
||||
}
|
||||
return CryptoJS.enc.Hex.parse(iv.map(b => b.toString(16).padStart(2, '0')).join(''))
|
||||
}
|
||||
67
src/utils/request.js
Normal file
67
src/utils/request.js
Normal file
@@ -0,0 +1,67 @@
|
||||
// utils/request.js
|
||||
// #ifdef APP
|
||||
const BASE_URL = 'https://app.quannengcha.com/api/v1'
|
||||
// const BASE_URL = 'https://6m4685017o.goho.co/api/v1'
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifndef APP
|
||||
const BASE_URL = '/api/v1'
|
||||
// #endif
|
||||
|
||||
function request(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 请求拦截器逻辑
|
||||
if (!options.hideLoading) {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
}
|
||||
|
||||
// 添加公共请求头,例如 token
|
||||
const token = uni.getStorageSync('token')
|
||||
options.header = {
|
||||
...options.header,
|
||||
Authorization: `${token}`,
|
||||
}
|
||||
// 如果是 GET 请求,并且有参数,将参数拼接到 URL
|
||||
let url = BASE_URL + options.url
|
||||
if (options.method === 'GET' && options.params) {
|
||||
const queryParams = Object.keys(options.params)
|
||||
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(options.params[key])}`)
|
||||
.join('&')
|
||||
url += `?${queryParams}`
|
||||
}
|
||||
uni.request({
|
||||
url,
|
||||
method: options.method || 'GET',
|
||||
data: options.method === 'GET' ? {} : options.data,
|
||||
header: options.header,
|
||||
success: (res) => {
|
||||
// 响应拦截器逻辑
|
||||
if (res.statusCode === 200) {
|
||||
resolve(res.data)
|
||||
}
|
||||
else if (res.statusCode === 401) {
|
||||
uni.removeStorageSync('token')
|
||||
uni.redirectTo({
|
||||
url: '/pages/login',
|
||||
})
|
||||
}
|
||||
else {
|
||||
uni.showToast({ title: res.data.msg || '请求失败', icon: 'none' })
|
||||
reject(res.data)
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.showToast({ title: '网络错误', icon: 'none' })
|
||||
reject(err)
|
||||
},
|
||||
complete: () => {
|
||||
if (!options.hideLoading) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default request
|
||||
Reference in New Issue
Block a user