01两个函数是什么、怎么调
| 云函数 | LUA 函数 | |
|---|---|---|
| 接口号 | api_type = 18(执行远程函数) | api_type = 35(执行 LUA 函数) |
| 语言 | JavaScript(goja 引擎) | Lua 5.1(gopher-lua) |
| 脚本来源 | 管理后台「函数管理」按别名维护,客户端只需知道别名 | |
| 执行超时 | 3 秒 | 10 秒 |
| 并发控制 | 全局 64 并发槽(超了快速失败) | 60 次 / 分钟 / 用户 限频 |
| 函数数量 | 42 个核心函数完全对等(Lua 额外 3 个别名,共 45 个) | |
// 客户端调用示例(所有语言 SDK 相同,只是 api_type 不同)
// LUA 函数:api_type=35,参数 {"alias":"脚本别名","params":{业务参数}}
// 云函数 :api_type=18,参数 {"alias":"函数别名","params":{业务参数}}
02安全模型
脚本语言本体只有计算能力;一切外部能力(HTTP、Redis、KV、点数、封号)都来自下面列出的内置函数,且函数按别名维护、按用户限频。
函数内已封禁
os / io / package / require / debug / loadfile / dofile,脚本无法读文件、起进程、加载库。Redis 未配置时相关函数安全回退(返回空 / 假),脚本逻辑不应依赖其成功。03内置函数参考
以下函数在两个远程函数中均可使用,签名一致。标注 受控 的函数会修改服务器数据,请在后台确认后再启用对应脚本。
上下文 6
| 函数 | 说明 |
|---|---|
| getUser() | 返回当前登录用户信息(含机器码、到期时间等,字段以实际响应为准) |
| getApp() | 返回当前应用信息 |
| now() | 当前 Unix 时间戳(秒) |
| nowMs() | 当前 Unix 时间戳(毫秒) |
| nowText() | 当前时间文本(YYYY-MM-DD HH:mm:ss) |
| client_ip() | 客户端 IP |
哈希与签名 5
| 函数 | 说明 |
|---|---|
| md5(str) | MD5 哈希,返回 32 位十六进制 |
| sha256Hex(str) | SHA256 哈希,返回 64 位十六进制(Lua 别名:sha256) |
| hmacSha256(s, k) | HMAC-SHA256,k 为密钥 |
| signData(input, key) | 带时间戳的签名(HMAC-SHA256,截断 32 位大写) |
| verifySign(input, key, sign, ts?) | 验签,返回布尔值 |
加密 6
| 函数 | 说明 |
|---|---|
| aesGcmEncrypt(plain, hexKey, aad?) | AES-256-GCM 加密,返回 base64(nonce + 密文 + tag) |
| aesGcmDecrypt(b64, hexKey, aad?) | AES-256-GCM 解密(失败抛错) |
| chachaEncrypt(plain, hexKey, aad?) | ChaCha20-Poly1305 加密 |
| chachaDecrypt(b64, hexKey, aad?) | ChaCha20-Poly1305 解密 |
| xorEncrypt(text, key) | XOR 加密(Base64 输出) |
| xorDecrypt(b64, key) | XOR 解密 |
编码与随机 4
| 函数 | 说明 |
|---|---|
| base64Encode(str) | Base64 编码(Lua 别名:b64encode) |
| base64Decode(str) | Base64 解码(Lua 别名:b64decode) |
| randomHex(n?) | 随机十六进制字符串(n = 字节数,默认 16) |
| uuid() | UUID v4 |
HTTP 出网 2
| 函数 | 说明 |
|---|---|
| httpGet(url, headers?) | GET 请求,headers 为 table 可选;内置 SSRF 防护:目标解析到内网 / 回环 / 保留地址会被拦截 |
| httpPost(url, body, headers?) | POST 请求,body 为字符串按文本发送、为对象自动 JSON 序列化 |
allow_network 开关:每个函数(别名)在后台有独立的联网权限开关。未开启时调用 httpGet / httpPost 返回错误「当前函数未开启联网(allow_network=0)」。SSRF 防护始终生效:脚本无法访问 127.0.0.1、内网网段、链路本地等保留地址。
Redis 缓存 4
| 函数 | 说明 |
|---|---|
| redisGet(k) | 读取(键自动加应用前缀隔离;不存在 / 未配置返回空) |
| redisSet(k, v, ttl?) | 写入(ttl 秒,可选) |
| redisSetNX(k, v, ttl?) | 原子写入(不存在时才设置——做锁 / 防重放用) |
| redisDel(k) | 删除 |
KV 缓存 5
| 函数 | 说明 |
|---|---|
| kvGet(key, scope?) | 读取 KV(scope 默认 app;user = 按用户隔离) |
| kvSet(key, value, scope?) | 写入 |
| kvDel(key, scope?) | 删除 |
| kvIncr(key, step?, scope?) | 原子自增(做计数器) |
| kvDecr(key, step?, scope?) | 原子自减 |
账号数据 2
| 函数 | 说明 |
|---|---|
| setRemark(str) | 设置当前用户备注 |
| setData(str) | 设置当前用户自定义数据(覆盖式) |
点数 2
| 函数 | 说明 |
|---|---|
| addPoints(n, biz?) | 增加点数(biz 为业务标识,用于幂等 / 审计) |
| deductPoints(n, biz?) | 扣减点数——biz 相同只扣一次(幂等) |
风控自处置 5
| 函数 | 说明 |
|---|---|
| banSelf() | 封停当前用户 |
| unbanSelf() | 解封当前用户 |
| unbindSelf() | 解除当前用户全部设备绑定 |
| addBlacklistSelf(type) | 把当前机器码(0) / IP(1) 加入黑名单 |
| getDevices() | 获取当前用户设备列表 |
混淆 1
| 函数 | 说明 |
|---|---|
| mathMix(a, b, c, d) | 整数混淆计算(自定义算法,用于授权码 / 校验值生成) |
04完整示例
Lua(接口 35)—— 风控判定 + 业务放行
-- 脚本别名:check_risk
-- 逻辑:设备数超 3 台且 IP 归属地异常 → 拉黑;否则返回业务数据
local user = getUser()
local devices = getDevices()
-- 记录访问(KV 计数,按用户隔离)
local visits = kvIncr("visit_count", 1, "user")
-- Redis 防重放:同一用户 10 秒内重复请求直接拒绝
local lock = redisSetNX("req:" .. client_ip(), "1", 10)
if not lock then
return {code = 429, msg = "请求过于频繁"}
end
-- 点数业务:每次调用扣 1 点(幂等标记防重复扣)
deductPoints(1, "check_risk-" .. nowMs())
return {
visits = visits,
devices = #devices,
expires = user.expires
}
JavaScript(接口 18)—— 调第三方接口 + 数据加工
// 脚本别名:query_exchange
// 逻辑:调外部汇率接口,按用户点数折算
var resp = httpPost("https://api.example.com/rate", JSON.stringify({base: "CNY"}), {})
var rate = JSON.parse(resp).rate
var user = getUser()
return {
points: user.points,
usd_value: user.points * rate
}
05使用红线与建议
- 先用测试账号验证:
banSelf / deductPoints / setData会真实修改数据——写好脚本先用测试卡跑通再上生产。 - 扣点必须带 biz:
deductPoints(n, biz)的 biz 相同只扣一次,防止脚本重试导致重复扣费。 - 风控脚本加抖动:机械等间隔的调用模式会被时序指纹识别,脚本内不要写死循环轮询。
- 超时预算:Lua 10 秒 / goja 3 秒,httpGet / httpPost 计入超时——调慢接口的脚本注意预算。
- Redis 是缓存不是存储:未配置或过期会返回空,关键数据落 KV 或账号数据。
- 封停拉黑玩法:建一个文档不公开的脚本别名(如 debug_helper),命中即
addBlacklistSelf(0)——精准识别逆向者。