8.3 KiB
Raw Blame History

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。新版本必须传 37744403887950;老版本不传时回退到环境变量 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 分钟。后续 ossdatacollectdatabugreportmultilingualreportquestionnaire 上传在身份缓存有效期内可以跳过实时 Steam API 校验。

STS 上传凭证缓存命中条件(同时满足):

  1. 版本号与请求一致(null 视为老版本,需严格匹配)
  2. 令牌签发时间在 5 分钟以内
  3. 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 有效期 90015 分钟) 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和目标路径防止客户端篡改上传目标。
  • 版本隔离:不同版本的客户端使用不同路径前缀,令牌不可跨版本复用。