255 lines
7.5 KiB
TypeScript
255 lines
7.5 KiB
TypeScript
// import CryptoJS from "crypto-js";
|
||
|
||
|
||
import GameData from '../GameData';
|
||
import CryptoJS = require('./crypto-js.min.js'); //引用AES源码js
|
||
|
||
// import axios from 'axios'
|
||
const {ccclass, property} = cc._decorator;
|
||
|
||
@ccclass
|
||
export default class HttpUtil extends cc.Component {
|
||
//排行榜type2为获取,type1为上传
|
||
static async rankData(type,callback,data): Promise<any> {
|
||
data.gameId = GameData._instance.GM_INFO.gameId;
|
||
data.userId = GameData._instance.GM_INFO.userId;
|
||
const time = Math.floor((new Date().getTime()) / 1000)
|
||
const url = apiSign(`/api/get/rank/data?gameId=${config.gameId}&dataType=${type}&time=${time}`, data)
|
||
this.httpPost(url,data,callback);
|
||
}
|
||
|
||
static async uploadUserLogData(data,callback): Promise<any> {
|
||
data.gameId = GameData._instance.GM_INFO.gameId;
|
||
data.userId = GameData._instance.GM_INFO.userId;
|
||
const url = '/log/collect/data';
|
||
this.httpPost(url,data,callback);
|
||
}
|
||
//暂时用不到
|
||
static async getUserRecord(data,callback): Promise<any> {
|
||
data.gameId = GameData._instance.GM_INFO.gameId;
|
||
data.userId = GameData._instance.GM_INFO.userId;
|
||
const time = Math.floor((new Date().getTime()) / 1000)
|
||
const url = apiSign(`/api/get/user/data?gameId=${config.gameId}&time=${time}`, data)
|
||
this.httpPost(url,data,callback);
|
||
}
|
||
|
||
static httpPost(url,data,callBack){
|
||
data.gameId = GameData._instance.GM_INFO.gameId;
|
||
data.userId = GameData._instance.GM_INFO.userId;
|
||
var urlData = "http://api.sparkus.cn" + url;
|
||
// console.log("params:",JSON.stringify(data));
|
||
let xhr = new XMLHttpRequest();
|
||
xhr.open('POST', urlData);
|
||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||
xhr.onreadystatechange = function () {
|
||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||
var data = xhr.responseText;
|
||
if(!data){
|
||
// console.log("初始化失败");
|
||
return;
|
||
}
|
||
var json = JSON.parse(data);
|
||
// console.log('http success:' + json);
|
||
callBack(json);
|
||
}
|
||
else{
|
||
// var json = JSON.parse(data);
|
||
// console.log('http fail:' + url);
|
||
callBack(json);
|
||
}
|
||
};
|
||
xhr.send(JSON.stringify(data));
|
||
}
|
||
|
||
static httpGet(url,callBack){
|
||
var urlData = "http://api.sparkus.cn" + url;
|
||
console.log(urlData);
|
||
let xhr = new XMLHttpRequest();
|
||
xhr.open('GET', urlData);
|
||
xhr.setRequestHeader('Content-Type', 'text/plain');
|
||
|
||
xhr.onreadystatechange = function () {
|
||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||
var data = xhr.responseText;
|
||
if(data){
|
||
var json = JSON.parse(data);
|
||
console.info('http success:' + json);
|
||
callBack(json);
|
||
}
|
||
else callBack(data);
|
||
}
|
||
else{
|
||
console.info('http fail:' + url);
|
||
callBack(null);
|
||
}
|
||
};
|
||
xhr.send();
|
||
}
|
||
}
|
||
|
||
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}`
|
||
}
|
||
|