Game Upload Function 服务说明
概述
这是一个运行在阿里云函数计算上的 HTTP 服务,为游戏客户端提供安全的 OSS 文件上传凭证。整体流程为:Steam 身份验证 → STS 临时令牌签发 → Post Policy 生成 → 缓存管理。
核心流程
客户端请求
│
▼
[1] 查询 Tablestore 缓存(版本号匹配 + 未过期)
│
├─ 命中 ──▶ 直接返回缓存令牌
│
└─ 未命中
│
▼
[2] 调用 Steam Web API 验证 AuthTicket(最多重试 3 次)
│
├─ 验证失败 ──▶ 返回 403
│
└─ 验证通过
│
▼
[3] 调用阿里云 STS 接口申请临时凭证(有效期 15 分钟)
│
▼
[4] 生成 OSS Post Policy + HMAC-SHA1 签名
│
▼
[5] 将令牌写入 Tablestore 缓存
│
▼
返回令牌给客户端
接口说明
请求
| 项目 | 值 |
|---|---|
| 方法 | POST |
| Content-Type | application/json |
| 最大请求体 | 1024 字节 |
请求体字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
steamId |
string | 是 | 玩家的 Steam ID |
authTicket |
string | 是 | Steam 客户端生成的 Auth Ticket(十六进制字符串) |
version |
string | 否 | 客户端版本号,不传则视为老版本 |
示例:
{
"steamId": "76561198xxxxxxxxx",
"authTicket": "0100000...",
"version": "1.2.3"
}
响应
成功(200):
| 字段 | 说明 |
|---|---|
accessKeyId |
STS 临时 AccessKeyId |
accessKeySecret |
STS 临时 AccessKeySecret |
securityToken |
STS 安全令牌 |
endpoint |
OSS 地址(oss-cn-shanghai.aliyuncs.com) |
bucket |
OSS Bucket 名称 |
objectKey |
上传目标路径(见下方路径规则) |
policy |
Base64 编码的 Post Policy |
signature |
Policy 的 HMAC-SHA1 签名 |
expiresIn |
令牌剩余有效期(秒) |
失败响应:
| HTTP 状态码 | 原因 |
|---|---|
| 400 | 缺少必要参数(steamId 或 authTicket) |
| 403 | Steam 身份验证失败 |
| 405 | 请求方法不为 POST |
| 413 | 请求体超过 1024 字节 |
| 500 | 服务器内部错误或环境变量缺失 |
OSS 上传路径规则
有版本号:{version}/{steamId}/{timestamp}.dat
无版本号:common/{steamId}/{timestamp}.dat
STS 权限策略仅允许写入该精确路径,最小化权限范围。
缓存机制
使用 阿里云 Tablestore(表名:Players,主键:PlayerId)缓存 STS 令牌,避免频繁调用 Steam API 和 STS 接口。
缓存命中条件(同时满足):
- 版本号与请求一致(
null视为老版本,需严格匹配) - 令牌签发时间在 5 分钟以内
- STS 令牌剩余有效期超过 2 分钟
Tablestore 存储字段:
| 字段 | 说明 |
|---|---|
PlayerId(主键) |
Steam ID |
accessKeyId |
STS 临时凭证 |
accessKeySecret |
STS 临时凭证 |
securityToken |
STS 安全令牌 |
endpoint / bucket / objectKey |
OSS 上传信息 |
policy / signature |
Post Policy 签名信息 |
issuedAt |
令牌签发时间戳(毫秒) |
stsExpireAt |
STS 过期时间戳(毫秒) |
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 |
Steam App ID |
OTS_ENDPOINT |
Tablestore 实例 Endpoint |
OTS_INSTANCE |
Tablestore 实例名称 |
关键参数
| 参数 | 值 | 说明 |
|---|---|---|
| 服务端口 | 9000 |
HTTP 监听端口 |
| 最大请求体 | 1024 字节 |
防止过大请求 |
| 最大上传文件 | 3 MB |
Post Policy 中限制的文件大小 |
| STS 有效期 | 900 秒(15 分钟) |
STS 临时凭证有效时长 |
| 缓存有效期 | 5 分钟 |
Tablestore 缓存的最长复用时间 |
| Steam API 超时 | 15 秒 |
单次 Steam 验证请求超时时间 |
| Steam API 重试 | 3 次 |
验证失败后最多重试次数 |
安全设计要点
- Steam 身份验证:每次缓存未命中时强制调用 Steam API 验证票据真实性,并比对 SteamID 防止伪造。
- 最小权限 STS:每个令牌的 OSS 写入权限仅限于带时间戳的精确路径,无法覆盖其他玩家的文件。
- Post Policy 签名:限制上传文件大小(≤3MB)和目标路径,防止客户端篡改上传目标。
- 版本隔离:不同版本的客户端使用不同路径前缀,令牌不可跨版本复用。