8.3 KiB
Game Upload Function 服务说明
概述
这是一个运行在阿里云函数计算上的 HTTP 服务,为游戏客户端提供安全的 OSS 文件上传凭证。整体流程为:Steam 身份预校验/缓存 → STS 临时令牌签发 → Post Policy 生成 → 上传凭证缓存。
核心流程
客户端请求
│
▼
[0] action=steamauth ?
│
├─ 是 ──▶ 验证 Steam AuthTicket,写入 Steam 身份缓存,返回 expiresIn
│
└─ 否
│
▼
[1] 查询 STS 上传凭证缓存(版本号匹配 + 未过期)
│
├─ 命中 ──▶ 直接返回缓存令牌
│
└─ 未命中
│
▼
[2] 查询 Steam 身份缓存
│
├─ 命中 ──▶ 跳过实时 Steam API 校验
│
└─ 未命中
│
▼
[3] 调用 Steam Web API 验证 AuthTicket(使用 steamAppId,最多重试 2 次)
│
├─ 验证失败 ──▶ 返回 403
│
└─ 验证通过
│
▼
[4] 调用阿里云 STS 接口申请临时凭证(有效期 15 分钟)
│
▼
[5] 生成 OSS Post Policy + HMAC-SHA1 签名
│
▼
[6] 将上传凭证写入 Tablestore 缓存
│
▼
返回令牌给客户端
接口说明
请求
| 项目 | 值 |
|---|---|
| 方法 | POST |
| Content-Type | application/json |
| 最大请求体 | 1024 字节 |
请求体字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
steamId |
string | 是 | 玩家的 Steam ID |
steamAppId |
string | 否 | 客户端当前 Steam AppID。新版本必须传 3774440 或 3887950;老版本不传时回退到环境变量 STEAM_APP_ID |
authTicket |
string | 条件必填 | Steam 客户端生成的 Auth Ticket(十六进制字符串)。首次预校验或身份缓存未命中时必须提供 |
version |
string | 否 | 客户端版本号,不传则视为老版本 |
action |
string | 否 | steamauth 表示只做 Steam 预校验;不传则进入上传凭证流程 |
type |
string | 否 | 上传类型:ossdata(默认) / collectdata / bugreport / multilingualreport / questionnaire |
示例:
{
"steamId": "76561198xxxxxxxxx",
"steamAppId": "3774440",
"authTicket": "0100000...",
"version": "1.2.3"
}
响应
上传凭证成功(200):
| 字段 | 说明 |
|---|---|
accessKeyId |
STS 临时 AccessKeyId |
accessKeySecret |
STS 临时 AccessKeySecret |
securityToken |
STS 安全令牌 |
steamAppId |
本次 Steam 校验使用的 AppID |
endpoint |
OSS 地址(oss-cn-shanghai.aliyuncs.com) |
bucket |
OSS Bucket 名称 |
objectKey |
上传目标路径(见下方路径规则) |
policy |
Base64 编码的 Post Policy |
signature |
Policy 的 HMAC-SHA1 签名 |
expiresIn |
令牌剩余有效期(秒) |
Steam 预校验成功(200):
| 字段 | 说明 |
|---|---|
success |
是否成功 |
cached |
是否直接命中已有 Steam 身份缓存 |
steamId |
玩家 Steam ID |
version |
客户端版本号 |
expiresIn |
Steam 身份缓存剩余有效期(秒) |
失败响应:
| HTTP 状态码 | 原因 |
|---|---|
| 400 | 缺少 steamId,或身份缓存未命中且缺少 authTicket |
| 403 | Steam 身份验证失败 |
| 405 | 请求方法不为 POST |
| 413 | 请求体超过 1024 字节 |
| 500 | 服务器内部错误或环境变量缺失 |
OSS 上传路径规则
ossdata:
有版本号:{version}/{steamId}/{timestamp}.dat
无版本号:common/{steamId}/{timestamp}.dat
collectdata:
有版本号:collect/{version}/{steamId}/{timestamp}.dat
无版本号:collect/common/{steamId}/{timestamp}.dat
bugreport:
有版本号:bugreport/{version}/{steamId}/{timestamp}-{random}.zip
无版本号:bugreport/common/{steamId}/{timestamp}-{random}.zip
multilingualreport:
有版本号:multilingualreport/{version}/{steamId}/{timestamp}-{random}.zip
无版本号:multilingualreport/common/{steamId}/{timestamp}-{random}.zip
questionnaire:
有版本号:questionnaire/{version}/{steamId}/{timestamp}-{random}.json
无版本号:questionnaire/common/{steamId}/{timestamp}-{random}.json
STS 权限策略仅允许写入该精确路径,最小化权限范围。
bugreport 用于玩家主动汇报,上传 zip 包,最大 10MB。该类型每次请求都会生成新 objectKey,不复用 Tablestore 缓存,避免连续提交覆盖同一个对象。
multilingualreport 用于玩家上报有问题的多语言文本,上传 zip 包,最大 1MB。内容包含 manifest.json、玩家选择的字符串和玩家自述,同样每次请求生成新 objectKey,不复用 Tablestore 缓存。
questionnaire 用于玩家问卷答卷,上传 JSON 文件,最大 512KB。该类型每次请求生成新 objectKey,不复用 Tablestore 缓存。
缓存机制
使用 阿里云 Tablestore(表名:Players,主键:PlayerId)缓存 Steam 身份和 STS 上传凭证,避免频繁调用 Steam API 和 STS 接口。
Steam 身份缓存:
客户端可以在 Steam 就绪后发送 action=steamauth,服务端验证通过后写入 {steamId}#steamauth#{steamAppId},有效期 10 分钟。后续 ossdata、collectdata、bugreport、multilingualreport、questionnaire 上传在身份缓存有效期内可以跳过实时 Steam API 校验。
STS 上传凭证缓存命中条件(同时满足):
- 版本号与请求一致(
null视为老版本,需严格匹配) - 令牌签发时间在 5 分钟以内
- STS 令牌剩余有效期超过 2 分钟
Tablestore 存储字段:
| 字段 | 说明 |
|---|---|
PlayerId(主键) |
{steamId}#{type}#{steamAppId},如 7656...#ossdata#3774440 |
accessKeyId |
STS 临时凭证 |
accessKeySecret |
STS 临时凭证 |
securityToken |
STS 安全令牌 |
endpoint / bucket / objectKey |
OSS 上传信息 |
policy / signature |
Post Policy 签名信息 |
issuedAt |
令牌签发时间戳(毫秒) |
stsExpireAt |
STS 过期时间戳(毫秒) |
steamAppId |
Steam AppID |
version |
客户端版本号(老版本存空字符串) |
环境变量
| 变量名 | 说明 |
|---|---|
ACCESS_KEY_ID |
阿里云主账号 AccessKeyId |
ACCESS_KEY_SECRET |
阿里云主账号 AccessKeySecret |
ROLE_ARN |
STS 扮演的 RAM 角色 ARN |
BUCKET_NAME |
OSS Bucket 名称 |
STEAM_API_KEY |
Steam Web API Key |
STEAM_APP_ID |
老客户端未传 steamAppId 时的默认 Steam App ID |
STEAM_ALLOWED_APP_IDS |
可选,允许的 Steam AppID 列表。默认包含 3774440,3887950 |
OTS_ENDPOINT |
Tablestore 实例 Endpoint |
OTS_INSTANCE |
Tablestore 实例名称 |
关键参数
| 参数 | 值 | 说明 |
|---|---|---|
| 服务端口 | 9000 |
HTTP 监听端口 |
| 最大请求体 | 1024 字节 |
防止过大请求 |
| 最大上传文件 | 3 MB / 10 MB / 1 MB / 512 KB |
普通数据 / 玩家 Bug 汇报 / 玩家多语言汇报 / 玩家问卷答卷的 Post Policy 限制 |
| STS 有效期 | 900 秒(15 分钟) |
STS 临时凭证有效时长 |
| 缓存有效期 | 5 分钟 |
Tablestore 缓存的最长复用时间 |
| Steam 身份缓存 | 10 分钟 |
预校验通过后的身份复用时间 |
| Steam API 超时 | 8 秒 |
单次 Steam 验证请求超时时间 |
| Steam API 重试 | 2 次 |
验证失败后最多重试次数 |
安全设计要点
- Steam 身份验证:服务端只接受
3774440/3887950等允许的 AppID,并用客户端上传的steamAppId调用 Steam API;身份缓存命中时复用预校验结果,未命中时强制验证票据真实性并比对 SteamID 防止伪造。 - 最小权限 STS:每个令牌的 OSS 写入权限仅限于带时间戳的精确路径,无法覆盖其他玩家的文件。
- Post Policy 签名:限制上传文件大小(普通数据≤3MB,玩家 Bug 汇报≤10MB,玩家多语言汇报≤1MB,玩家问卷答卷≤512KB)和目标路径,防止客户端篡改上传目标。
- 版本隔离:不同版本的客户端使用不同路径前缀,令牌不可跨版本复用。