222 lines
6.3 KiB
TypeScript
222 lines
6.3 KiB
TypeScript
|
|
const {ccclass, property} = cc._decorator;
|
|
import CryptoJS = require('./crypto-js.min.js'); //引用AES源码js
|
|
|
|
const BASE_URL = "http://api.sparkus.cn";
|
|
//只负责网络接口 次类只负责和后端交互,不负责处理数据 数据处理在GameTool
|
|
@ccclass
|
|
export default class HttpUtil extends cc.Component {
|
|
//排行榜
|
|
static async rankData(type,callback,data): Promise<any> {
|
|
const time = Math.floor((new Date().getTime()) / 1000)
|
|
const url = apiSign(`/api/get/rank/data?gameId=${config.gameId}&dataType=${type}&time=${time}`, data)
|
|
this.post(url,data,callback);
|
|
}
|
|
|
|
static async uploadUserLogData(data,callback): Promise<any> {
|
|
const url = '/log/collect/data';
|
|
this.post(url,data,callback);
|
|
}
|
|
//暂时用不到
|
|
static async getUserRecord(data,callback): Promise<any> {
|
|
const time = Math.floor((new Date().getTime()) / 1000)
|
|
const url = apiSign(`/api/get/user/data?gameId=${config.gameId}&time=${time}`, data)
|
|
this.post(url,data,callback);
|
|
}
|
|
static async post(url, data, callback) {
|
|
const response = await this.fetchData(url, data, 'POST');
|
|
callback && callback(response);
|
|
}
|
|
|
|
static async get(url, callback) {
|
|
const response = await this.fetchData(url, null, 'GET');
|
|
callback && callback(response);
|
|
}
|
|
|
|
static async fetchData(url, data, method) {
|
|
const fullUrl = `${BASE_URL}${url}`;
|
|
const headers = { 'Content-Type': 'application/json' };
|
|
const options = {
|
|
method,
|
|
headers,
|
|
body: data ? JSON.stringify(data) : null,
|
|
};
|
|
|
|
try {
|
|
const response = await fetch(fullUrl, options);
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error('Fetch error:', error);
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
function responseHandler(response: { data: any }) {
|
|
return response.data
|
|
}
|
|
// 响应拦截器
|
|
// Rq.interceptors.response.use(responseHandler)
|
|
const config = {
|
|
gameId: "100009",
|
|
secretKey: "CMNhOzBA",
|
|
EK:"hui231%1"
|
|
};
|
|
|
|
interface CrypotoType {
|
|
encryptByDES: any
|
|
decryptByDES: any
|
|
hmacSha256: any
|
|
}
|
|
|
|
class Crypoto implements CrypotoType {
|
|
// 加密的向明值,自己根据项目实际情况定,需要跟后端开发保持一致
|
|
private keyHex = this.getHetKey()
|
|
private getHetKey() {
|
|
return CryptoJS.enc.Utf8.parse(config.EK);
|
|
}
|
|
|
|
/** DES加密 */
|
|
encryptByDES(message: string, secret?: string) {
|
|
if(!message) {
|
|
return message
|
|
}
|
|
const key = secret? CryptoJS.enc.Utf8.parse(secret): this.keyHex
|
|
const encrypted = CryptoJS.DES.encrypt(message, key, {
|
|
mode: CryptoJS.mode.ECB,
|
|
padding: CryptoJS.pad.Pkcs7
|
|
});
|
|
return encrypted.toString()
|
|
}
|
|
|
|
/** DES解密 */
|
|
decryptByDES(message: string, secret?: string) {
|
|
const key = secret? CryptoJS.enc.Utf8.parse(secret): this.keyHex
|
|
|
|
const decrypted = CryptoJS.DES.decrypt({
|
|
ciphertext: CryptoJS.enc.Base64.parse(message)
|
|
}, key, {
|
|
mode: CryptoJS.mode.ECB,
|
|
padding: CryptoJS.pad.Pkcs7
|
|
})
|
|
|
|
return decrypted.toString(CryptoJS.enc.Utf8)
|
|
}
|
|
|
|
/** hmacSHA256加密 */
|
|
hmacSha256(message: string, secret?: string) {
|
|
const keyHex = secret? CryptoJS.enc.Utf8.parse(secret): this.keyHex
|
|
|
|
const hash = CryptoJS.HmacSHA256(message, keyHex);
|
|
return hash.toString()
|
|
}
|
|
|
|
/** hmacSHA256验证 */
|
|
verifyHmacSha256(message: string, signature: string) {
|
|
const hash = CryptoJS.HmacSHA256(message, this.keyHex);
|
|
return hash.toString() === signature
|
|
}
|
|
|
|
/** CBC加密 */
|
|
encryptCBC(word: string) {
|
|
if (!word) {
|
|
return word;
|
|
}
|
|
const srcs = CryptoJS.enc.Utf8.parse(word);
|
|
const encrypted = CryptoJS.AES.encrypt(srcs, this.keyHex, {
|
|
iv: this.keyHex,
|
|
mode: CryptoJS.mode.CBC,
|
|
padding: CryptoJS.pad.ZeroPadding
|
|
});
|
|
return encrypted.toString();
|
|
}
|
|
|
|
/** CBC解密 */
|
|
decryptCBC(word: string) {
|
|
if (!word) {
|
|
return word;
|
|
}
|
|
const encryptedHexStr = CryptoJS.enc.Hex.parse(word);
|
|
const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
|
|
const decrypt = CryptoJS.AES.decrypt(srcs, this.keyHex, {
|
|
iv: this.keyHex,
|
|
mode: CryptoJS.mode.CBC,
|
|
padding: CryptoJS.pad.ZeroPadding
|
|
});
|
|
const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
|
|
return decryptedStr.toString();
|
|
}
|
|
}
|
|
const fxCry = new Crypoto();
|
|
|
|
function isEmpty(data) {
|
|
return data === "" || data === null || data === undefined || data.length === 0 || JSON.stringify(data) == "{}"
|
|
}
|
|
|
|
function getQueryString(obj) {
|
|
// 首先对对象的键进行排序并过滤空值
|
|
const sortedKeys = Object.keys(obj).sort();
|
|
const sortedObj = {};
|
|
for (let i = 0; i < sortedKeys.length; i++) {
|
|
if (isEmpty(obj[sortedKeys[i]])) {
|
|
continue;
|
|
}
|
|
sortedObj[sortedKeys[i]] = obj[sortedKeys[i]];
|
|
}
|
|
|
|
// 然后将排序后的对象转换为查询字符串
|
|
const params = [];
|
|
for (const key in sortedObj) {
|
|
params.push(`${encodeURIComponent(key)}=${encodeURIComponent(sortedObj[key])}`);
|
|
}
|
|
return params.join('&');
|
|
}
|
|
|
|
|
|
/**
|
|
* 组装签名字符串
|
|
* @param string url: 请求地址
|
|
* @param string postStr: post参数的a=1&b=2
|
|
* @returns
|
|
*/
|
|
|
|
function genSignStr(url: string, postStr: string): string {
|
|
let lessUrl = url.replace('?', '')
|
|
lessUrl = lessUrl + "&" + postStr
|
|
return encodeURIComponent(fxCry.hmacSha256(lessUrl))
|
|
}
|
|
// 对参数进行统一urlencode
|
|
function urlencode(url: string): string {
|
|
const [baseUrl, queryString] = url.split("?", 2);
|
|
const params = new URLSearchParams(queryString);
|
|
return `${baseUrl}?${params.toString()}`;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param url {string} 接口地址
|
|
* @param params {object} 需要加密的参数对象
|
|
*/
|
|
function apiSign(url: string, params = {}) {
|
|
|
|
let convertUrl = url.trim()
|
|
if (convertUrl.indexOf('?') === -1) {
|
|
convertUrl += '?'
|
|
}
|
|
|
|
// 传入参数转换拼接字符串
|
|
let postStr = getQueryString(params)
|
|
|
|
const signedStr = genSignStr(convertUrl, postStr)
|
|
const encryptStr = `sign=${signedStr}`
|
|
|
|
let encryptSignStr = fxCry.encryptByDES(encryptStr, config.secretKey)
|
|
encryptSignStr = encodeURIComponent(encryptSignStr)
|
|
|
|
return `${urlencode(convertUrl)}&_p=${encryptSignStr}`
|
|
}
|
|
|