Apifox 公共脚本
2024年7月9日小于 1 分钟
自动登录脚本
实现功能
- token、accessToken的自动生成
- token自动过期
- 自动登录
- 登录接口和入参动态配置
- 根据开发环境动态切换配置
- 便捷切换登录用户
::: code-tabs#js
@tab 初始化脚本
// init.js
// 1. 初始化脚本
init = function () {
if (!pm.globals.has("appId"))
pm.globals.set("appId", 'ktna-im-plug-web')
if (!pm.globals.has("secret"))
pm.globals.set("secret", 'kdjb0fssepvd7lvqlfd51dtzm23ncmti')
if (!pm.globals.has("key"))
pm.globals.set("key", '05eir4d0xyq0x1gb')
if (!pm.environment.has("loginURL"))
pm.environment.set("loginURL", 'http://127.0.0.1:8080/login')
if (!pm.environment.has("activeUser"))
pm.environment.set("activeUser", 'defaultUser')
if (!pm.environment.has("defaultUser"))
pm.environment.set("defaultUser", '{"username":"19973504813","password":"123456"}')
if (!pm.environment.has("APP_TOKEN"))
pm.environment.set("APP_TOKEN", null)
if (!pm.environment.has("APP_TOKEN_EXPIRES"))
pm.environment.set("APP_TOKEN_EXPIRES", null)
if (!pm.environment.has("ACCESS_TOKEN"))
pm.environment.set("ACCESS_TOKEN", null)
if (!pm.environment.has("ACCESS_TOKEN_EXPIRES"))
pm.environment.set("ACCESS_TOKEN_EXPIRES", null)
}
generateAppToken = function () {
const appId = pm.globals.get("appId");
const secret = pm.globals.get("secret");
const key = pm.globals.get("key");
console.log("appToken生成:","appId: " + appId + "\n secret: " + secret + "\n key: " + key);
pm.test('全局变量【appToken配置[appId|secret|key]信息】检查', function () {
pm.expect(appId).to.not.be.empty;
pm.expect(secret).to.not.be.empty;
pm.expect(key).to.not.be.empty;
});
const jetLag = 0 // 服务器与本机时间差
let timestamp = new Date().getTime()
timestamp += Number(jetLag)
var cryptoJs = require("crypto-js");
var h256 = cryptoJs.HmacSHA256(secret + '.' + timestamp, key)
var btoa = require("btoa");
var bs6 = btoa(' {"appId":"' + appId + '","timestamp":' + timestamp + '}')
var appToken = bs6 + "." + h256;
if ('' != appId && '' != secret && '' != key) {
return appToken;
}
return appToken;
}
generateLoginRequest = function (token) {
const activeUser = pm.environment.get("activeUser")
const loginUser = pm.environment.get(activeUser)
const loginURL = pm.environment.get("loginURL")
const appToken = pm.environment.get("APP_TOKEN") ?? token ?? generateAppToken();
pm.test('环境变量 {loginURL:登录地址} 检查', function () {
pm.expect(loginURL).to.not.be.empty;
});
pm.test('环境变量 {activeUser:登录用户}【' + activeUser + '】检查', function () {
pm.expect(activeUser).to.not.be.empty;
});
const echoPostRequest = {
url: loginURL,
method: "POST",
header: {
"User-Agent": " Apifox/1.0.0 (https://apifox.com)",
"Accept": " */*",
"Content-Type": "application/json",
"appToken": appToken,
},
body: {
mode: 'raw',
raw: loginUser
}
};
return echoPostRequest
}
init()
@tab:active 登录脚本
// login.js
// 2. 登录脚本
var appToken = pm.environment.get("APP_TOKEN")
const appTokenExpires = pm.environment.get("APP_TOKEN_EXPIRES")
if (!appToken || (appTokenExpires && new Date(appTokenExpires) <= new Date())) {
appToken = generateAppToken()
console.log("设置环境变量【appToken】,值为\n" + appToken + "\n")
pm.environment.set('APP_TOKEN', appToken)
// 过期时间 向后偏移5分钟
let expireTime = new Date()
expireTime.setMinutes(expireTime.getMinutes() + 5)
pm.environment.set("APP_TOKEN_EXPIRES", expireTime)
}
var accessToken = pm.environment.get("ACCESS_TOKEN")
const accessTokenExpires = pm.environment.get("ACCESS_TOKEN_EXPIRES")
if (!accessToken || (accessTokenExpires && new Date(accessTokenExpires) <= new Date())) {
const request = generateLoginRequest(appToken)
console.log("登录请求入参:",JSON.parse(request.body.raw))
pm.sendRequest(request, function (err, res) {
if (err) {
console.log(err)
return
}
const ret = res.json();
pm.test('登录成功校验', function () {
pm.expect(res).to.have.property("code", 200)
pm.expect(res).to.have.property("status", "OK")
pm.expect(ret).to.have.any.keys('accessToken')
})
if ('accessToken' in ret) {
pm.environment.set("ACCESS_TOKEN", ret.accessToken)
console.log("设置环境变量【accessToken】,值为\n" + ret.accessToken + "\n")
// 过期时间 向后偏移2小时
let expireTime = new Date()
expireTime.setHours(expireTime.getHours() + 2)
pm.environment.set("ACCESS_TOKEN_EXPIRES", expireTime)
// 更新header
pm.request.headers.upsert({ key: "accessToken", value: ret.accessToken })
} else {
console.log("登录失败", ret);
}
})
}
pm.request.headers.upsert({ key: "appToken", value: appToken })
pm.request.headers.upsert({ key: "accessToken", value: accessToken })
@tab TOKEN【后置清理】
// process.js
// TOKEN【后置清理】
// console.log('response', pm.response);
// console.log('json', pm.response.json());
// console.log('text', pm.response.text());
// console.log('code', pm.response.code, pm.response.code == 200);
// console.log('status', pm.response.status, pm.response.status == "OK");
// if(pm.response.code == 200) return
var header = pm.response.headers.get("Content-Type")
if (header.includes("application/json")) {
// console.log("Content-Type:" + header)
var ret = pm.response.json()
// console.log('errorCode',"errorCode" in ret,ret.errorCode,ret)
if ("errorCode" in ret) {
if (ret.errorCode == 40100 || ret.errorCode == 40101 || ret.errorCode == 40102 || ret.errorCode == 40103) {
console.log("清理 APP_TOKEN & ACCESS_TOKEN")
pm.environment.unset("ACCESS_TOKEN");
pm.environment.unset('APP_TOKEN');
pm.environment.unset('ACCESS_TOKEN_EXPIRES');
pm.environment.unset('APP_TOKEN_EXPIRES');
}
}
return
}
if (pm.response.code == 200) {
console.error('接口异常', pm.response)
}
:::
效果预览
解释说明
- loginURL: 登录请求地址
- acticeUser: 激活用户配置
- defaultUser: 默认登录信息
- TH8989: 自定义的登录用户信息
- APP_TOKEN: 生成的app_token
- APP_TOKEN_EXPIRES: app_token过期时间
- ACCESS_TOKEN:生成的accessToken
- ACCESS_TOKEN_EXPIRES: accessToken的过期时间
IDEA Apifox插件自定义配置
相关信息
IDEA 设置:Settings -> Apifox Helper -> 代码识别 -> 自定义规则
效果: 自定义注解校验
参考官网:https://apifox.com/help/applications-and-plugins/idea/start
#configs
#dev=false
#auto.format.url=true
#max.deep=10
#max.elements=512
###set resolveMulti = first
# define var
number_min=-9999
number_max=9999
float_dmin=2
java_integer_types=["java.lang.Integer","int","java.lang.Long","long","java.lang.Short","short","java.math.BigInteger"]
java_float_types=["java.lang.String","java.lang.Float","float","java.lang.Double","double","java.math.BigDecimal"]
# example
field.example[groovy:it.hasAnn("io.swagger.annotations.ApiModelProperty")&&""!=it.ann("io.swagger.annotations.ApiModelProperty","example")]=groovy:it.ann("io.swagger.annotations.ApiModelProperty","example")
# rules for com.custom.framework.domain.validator.constraints
param.required=@com.custom.framework.domain.validator.constraints.hv.NotBlank
param.required=@com.custom.framework.domain.validator.constraints.jv.NotNull
param.required=@com.custom.framework.domain.validator.constraints.hv.NotEmpty
field.required=@com.custom.framework.domain.validator.constraints.hv.NotBlank
field.required=@com.custom.framework.domain.validator.constraints.jv.NotNull
field.required=@com.custom.framework.domain.validator.constraints.hv.NotEmpty
field.schema.permit.null=@com.custom.framework.domain.validator.constraints.hv.NotBlank
field.schema.permit.null=@com.custom.framework.domain.validator.constraints.jv.NotNull
field.schema.permit.null=@com.custom.framework.domain.validator.constraints.hv.NotEmpty
field.schema.permit.null=@io.swagger.annotations.ApiImplicitParam#required
field.schema.permit.null=@io.swagger.annotations.ApiModelProperty#required
# Max+Min
field.mock[groovy:it.hasAnn("com.custom.framework.domain.validator.constraints.jv.Max")&&it.hasAnn("com.custom.framework.domain.validator.constraints.jv.Min")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer("+it.ann("com.custom.framework.domain.validator.constraints.jv.Min")+","+it.ann("com.custom.framework.domain.validator.constraints.jv.Max")+")"
field.mock[groovy:it.hasAnn("com.custom.framework.domain.validator.constraints.jv.Max")&&it.hasAnn("com.custom.framework.domain.validator.constraints.jv.Min")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float("+it.ann("com.custom.framework.domain.validator.constraints.jv.Min")+","+it.ann("com.custom.framework.domain.validator.constraints.jv.Max")+",${float_dmin})"
# Max|Min
field.mock[groovy:it.hasAnn("com.custom.framework.domain.validator.constraints.jv.Max")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer(0,"+it.ann("com.custom.framework.domain.validator.constraints.jv.Max")+")"
field.mock[groovy:it.hasAnn("com.custom.framework.domain.validator.constraints.jv.Min")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer("+it.ann("com.custom.framework.domain.validator.constraints.jv.Min")+")"
field.mock[groovy:it.hasAnn("com.custom.framework.domain.validator.constraints.jv.Max")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float(0,"+it.ann("com.custom.framework.domain.validator.constraints.jv.Max")+")"
field.mock[groovy:it.hasAnn("com.custom.framework.domain.validator.constraints.jv.Min")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float("+it.ann("com.custom.framework.domain.validator.constraints.jv.Min")+",${number_max},${float_dmin})"
# Max、Min -advanced
field.advanced[@com.custom.framework.domain.validator.constraints.jv.Min]=groovy:```
return [maximum:it.ann("com.custom.framework.domain.validator.constraints.jv.Min")]
```
field.advanced[@com.custom.framework.domain.validator.constraints.jv.Max]=groovy:```
return [minimum:it.ann("com.custom.framework.domain.validator.constraints.jv.Max")]
```
# Size
field.mock[groovy:it.hasAnn("com.custom.framework.domain.validator.constraints.jv.Size")&&it.jsonType().name()=="java.lang.String"]=groovy:```
def ann = it.annMap("com.custom.framework.domain.validator.constraints.jv.Size")
if(ann.containsKey("min")&&ann.containsKey("max")){
return "@string("+ann["min"]+","+ann["max"]+")"
}else if(ann.containsKey("min")){
return "@string("+ann["min"]+")"
}else if(ann.containsKey("max")){
return "@string(0,"+ann["max"]+")"
}
```
field.advanced[@com.custom.framework.domain.validator.constraints.jv.Size]=groovy:```
def element = (it.jsonType().name() == "java.lang.String")?"Length":"Items"
def ann = it.annMap("com.custom.framework.domain.validator.constraints.jv.Size")
def advanced = [:]
if(ann.containsKey("min")){
advanced["min"+element] = ann["min"]
}
if(ann.containsKey("max")){
advanced["max"+element] = ann["max"]
}
return advanced
```
# NotEmpty
field.advanced[@com.custom.framework.domain.validator.constraints.hv.NotEmpty]=groovy:```
def element = (it.jsonType().name() == "java.lang.String")?"Length":"Items"
def advanced = [:]
advanced["min"+element] = 1
return advanced
```
# 枚举
enum.use.custom[groovy:it.isExtend("com.ktna.cloud.base.core.constant.EnumProcessor")]=code