Apifox 自动登录 + 请求加密[自用]

发布时间 2023-11-07 11:27:36作者: SpringCore
var jsrsasign = require("jsrsasign");
var cryptoJs = require("crypto-js");


var accessToken = pm.environment.get("ACCESS_TOKEN");
var accessTokenExpires = pm.environment.get("ACCESS_TOKEN_EXPIRES");
let request_encryption = pm.environment.get("REQUEST_ENCRYPTION");
let login_public_key = pm.environment.get("LOGIN_PUBLIC_KEY");
if (!login_public_key) {
  login_public_key = pm.globals.get('LOGIN_PUBLIC_KEY');
}
var public_key = pm.environment.get("PUBLIC_KEY");
if (!request_encryption) {
  request_encryption = pm.globals.get('REQUEST_ENCRYPTION');
}
if (
  !accessToken ||
  (accessTokenExpires && new Date(accessTokenExpires) <= new Date())
) {
  sendLoginRequest();
} else {
  if (accessToken && request_encryption == 1 && !public_key) {
    getPublicKeyRequest();
  } else {
    sendRequest();
  }
}

function sendRequest() {
  if (request_encryption == 1) {
    let randomKeys = random_keys(16);
    let headers = pm.request.headers;
    headers.add({
      key: "Publickey",
      value: public_key,
    });
    headers.add({
      key: "Randomkeys",
      value: randomKeys,
    });
    headers.add({
      key: "Specialkey",
      value: rsa_encrypt(randomKeys, public_key),
    });

    let contentType = pm.request.headers.get('content-type')
    if (
      contentType &&
      pm.request.body.raw &&
      contentType.toLowerCase().indexOf('application/json') !== -1
    ) {
      try {
        pm.request.body.update(aes_encrypt(pm.request.body.raw, randomKeys));
      } catch (e) {
        console.log('请求 body 不是 JSON 格式')
      }
    }
  }
}

function aes_encrypt(params, randomKey) {
  const srcs = cryptoJs.enc.Utf8.parse(
    typeof params === 'object' ? JSON.stringify(params) : params
  )
  const key = cryptoJs.enc.Utf8.parse(randomKey)
  const encryptedParams = cryptoJs.AES.encrypt(srcs, key, {
    iv: cryptoJs.enc.Utf8.parse('coreqi20231111'),
    mode: cryptoJs.mode.CBC,
    padding: cryptoJs.pad.Pkcs7,
  })
  return encryptedParams.toString()
}


function random_keys(n) {
  const charList = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  let str = ''
  let len = charList.length
  for (let i = 0; i < n; i++) {
    str += charList[Math.floor(Math.random() * len)]
  }
  return str
}

function rsa_encrypt(params, key) {
  console.log("key", key);
  let pubk = "-----BEGIN PUBLIC KEY-----" + key + "-----END PUBLIC KEY-----"
  let pub = jsrsasign.KEYUTIL.getKey(pubk);
  let enc = jsrsasign.KJUR.crypto.Cipher.encrypt(params, pub, 'RSA');
  return jsrsasign.hextob64(enc);
}


function getPublicKeyRequest() {
  const baseUrl = pm.request.getBaseUrl();
  const getPublicKeyRequest = {
    url: baseUrl + "/api/Login/GetLoginBasicInfo",
    method: "POST",
    header: {
      'User-Agent': 'Coreqi with fanqi',
      'Connection': 'keep-alive',
      'Accept': 'application/json',
      "Content-Type": "application/json",
      "Authorization": "Bearer " + accessToken,
    },
    body: {
      mode: 'raw',
    },
  };

  pm.sendRequest(getPublicKeyRequest, function (getErr, getRes) {
    if (getErr) {
      console.log(getErr);
    } else {
      public_key = getRes.json().publicKey;
      pm.environment.set("PUBLIC_KEY", public_key);
      sendRequest();
    }
  })
}


function sendLoginRequest() {
  const baseUrl = pm.request.getBaseUrl();
  let username = pm.environment.get("LOGIN_USERNAME");
  if (!username) {
    username = pm.globals.get('LOGIN_USERNAME');
  }
  let password = pm.environment.get("LOGIN_PASSWORD");
  if (!password) {
    password = pm.globals.get('LOGIN_PASSWORD');
  }

  let randomKeys = random_keys(16);
  const loginRequest = {
    url: baseUrl + "/api/Login/LoginByPwd",
    method: "POST",
    header: {
      'User-Agent': 'Coreqi with fanqi',
      'Connection': 'keep-alive',
      'Accept': 'application/text',
      "Content-Type": "application/json",
    },
    body: {
      mode: 'raw',
      raw: JSON.stringify({ LoginName: username, PassWord: password }),
    },
  };

  if (request_encryption == 1) {
    loginRequest.header.Publickey = login_public_key;
    loginRequest.header.Randomkeys = randomKeys;
    loginRequest.header.SpecialKey = rsa_encrypt(randomKeys, login_public_key);
    loginRequest.body.raw = aes_encrypt({ LoginName: username, PassWord: password }, randomKeys);
  }

  pm.sendRequest(loginRequest, function (err, res) {
    if (err) {
      console.log(err);
    } else {
      const token = res.text();
      accessToken = token;
      accessTokenExpires = new Date().getTime() + 1000 * 60 * 50;
      pm.environment.set("ACCESS_TOKEN", accessToken);
      pm.environment.set("ACCESS_TOKEN_EXPIRES", accessTokenExpires);
      getPublicKeyRequest();
    }
  });
}