绕过前端直接调度华为云 KooLabs 云实验:从 Vue 路由到调度 API

举报
yd_255011313 发表于 2026/10/27 13:48:26 2026/10/27
【摘要】 华为云控制台自动化三层鉴权排障:MFA 提示页路由循环、SSO TGC 单次消耗、KooLabs 联邦登录与 auth-token 鉴权。

想用脚本把云实验跑起来,第一反应是自动化点页面。我在这上面卡了两天,最后发现页面根本不是"点"的问题——卡片是 Vue 路由渲染的,`a[href]` 里只有分享按钮,点标题、点卡片容器、用 JS 找 `cursor:pointer` 的祖先再点,URL 始终停在 `/lab/`,路由一步都不跳。

真正的入口在接口层。记一下这条链路,都是实测出来的。

## 一、先找到鉴权 token 藏在哪

云实验的接口域是 `data.edu.huaweicloud.com`,但它**不用** `X-Auth-Token`。打开 `/lab` 页面后执行:

```javascript
sessionStorage.getItem('setToken')
```

拿到一个 685 字符的 JWT。这个值挂在自定义头里:

```
auth-token:
```

注意是 `auth-token`,全小写带连字符,和华为云 OpenAPI 的 `X-Auth-Token` 完全是两套东西。用错头会直接 401 或 403,而且错误信息不会告诉你头名写错了。

## 二、实验列表和剩余名额

两个不同前缀,很容易混:

```
GET /rest/developer/user/hdsandboxexpservice/v1/ware
→ {"result":{"experiment_list":[{"id":2325,"title":"10分钟入门装载国产操作系统的ECS",...}]}}

GET /rest/developer/servlet/hdsandboxuserservice/v1/
→ {"result":[{"experiment_id":2325,"free_quota":13},{"experiment_id":2417,"free_quota":33}]}
```

`free_quota` 是当日免费名额。这个数字每天刷新,是为后面埋的坑。

另外 `/rest/developer/servlet/hdsandboxexpservice/v1/s...`(被截断的那个)返回的是实验方向分类,不是实验本体,别拿错。

## 三、调度接口:全部是 POST

调度前缀是 `/rest/developer/user/hdsandboxschedulerservice/exercise`。这里有个反直觉的地方——**所有 GET 都返回 405**:

```
GET /exercise/2325/check-operation-status → 404
GET /exercise/check-operation-status?experiment_id=2325 → 405 Method Not Allowed
POST /exercise/check-operation-status?experiment_id=2325 → 200
```

405 是个好信号,它说明路径是对的,只是方法错了。404 反而说明路径本身不对。排障时先看状态码能省很多时间。

`POST /check-operation-status` 返回:

```json
{"result":{"remainUserTimes":2067,"preOccupyFreeSlots":true,
"operationStatisticsId":null,"spotsEnough":false,
"experiment_spot":0,"price":5,"times":3600}}
```

`price: 5` 是消耗的**实验点**(平台赠送的虚拟额度,不是钱),`times: 3600` 是可用时长(秒)。

启动:

```
POST /exercise/start {"experiment_id": 2325}
→ {"result": 504107}
```

返回的 `504107` 是 `operationStatisticsId`,即本次实验会话的 ID。

之后轮询实例:

```
POST /exercise/get-instance-info {"experiment_id": 2325}
```

实例就绪时 `result.instance_info` 会从 `null` 变成对象,分配期间一直是:

```json
{"result":{"instance_info":null,"stop_query_result":null,"account":null,"status":"0"}}
```

这个 `status: "0"` 很关键——它不是"正常",是"还没分配"。我第一次误判成启动成功,白等五分钟。

拿到实例后取免密登录链接:

```
POST /exercise/get-login-link {"experiment_id": 2325}
```

失败时会返回 `HD.314710026: cannot binding lab instance`,意思就是"实例还没绑到你身上",回到上一步继续等。

## 四、结束实验:字段名是下划线

结束接口有个坑,错误信息很误导:

```
POST /exercise/end {"experiment_id": 2325, "doneScene": 2}
→ 400 {"error_msg":"Invalid param error;doneScene 不能为空"}
```

明明传了 `doneScene`,它还说"不能为空"。换成下划线就好了:

```
POST /exercise/end {"experiment_id": 2325, "done_scene": 2}
→ 200 {"result": null}
```

`result: null` 就是成功。参数名是 `done_scene`,报错信息里的驼峰是后端框架自动转出来的,照着报错改参数名会被带偏。

我也试过把参数放 query:

```
POST /exercise/end?experiment_id=2325&doneScene=2
→ 400 {"error_msg":"Invalid param error, cannot convert the request"}
```

"cannot convert the request" 说明类型转换失败,通常意味着参数该在 body 里。这两个错误的区分挺有用:**「不能为空」是字段名不对,「无法转换」是位置不对**。

## 五、几个错误码的含义

| 错误码 | 含义 | 怎么处理 |
|---|---|---|
| `HD.31400001 Not Found` | 路径不对 | 换路径,别改方法 |
| `HD.31400001 Method Not Allowed` | 方法不对 | GET 换 POST |
| `HD.31420014 reduce lab points fail no auth do lab` | 扣实验点失败 | 当日免费名额耗尽,或账号无实验权限 |
| `HD.31420023 lab instance not exist or has end` | 实例不存在/已结束 | 会话过期或被回收 |
| `HD.314710026 cannot binding lab instance` | 实例未绑定 | 还没分配成功,继续轮询 |

`HD.31420014` 这个最坑:它不是"点数不够",`remainUserTimes` 显示还有 2067,但当日 `free_quota` 用完后,付费通道又走不通,就报这个。换句话说**免费名额是每日上限,不是余额扣减**。

## 六、一个实践上的建议

如果你的目标只是"让任务算完成",注意平台判定的是**实验操作行为**,不是"启动"这个动作本身。我启动过两次实验,成长中心的任务状态一直是未完成——因为环境里的任务(比如创建 VPC)没做。所以光调通 `start` 不够,得真的进沙箱把实验手册里的步骤走完。

反过来,`end` 一定要调。不调的话会话会挂到时长上限(`times: 3600`)才回收,期间那门实验的名额一直被你占着,当天想再开一门就会撞上 `HD.31420014`。这是我踩过的最贵的坑——自己把名额堵死了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。