Featured image of post 火山引擎体验中心逆向分析

火山引擎体验中心逆向分析

提醒

  • 文章很长,且没啥用,

  • 没有耐心的可以左转退出哩

为什么逆向

闲的

免责声明

本数据仅供学习参考,不得用于商业用途,且不提供任何成品和现有分析文件


基础认证流程

POST 请求,无需授权

1. getBindStatus

  • 最小化参数
    • Cookie.digest:任意 version4 uuid(首次请求随机生成,后续请求均为登录后的Cookie里获取,且必须携带)
  • 返回参数
    • Set-cookie.Csrf-Token(后续携带)

核心 API 调用流程(顺序强制),以下均为示例数据

1. CreateExperienceConversation(创建会话)

  • 最小化参数: Header的X-Csrf-Token(与Cookie中csrfToken值相同,但Cookie中的可加可不加,很怪)和Cookie的digest
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "ModelList": [
    {
      "EntityId": "deepseek-r1",
      "EntityName": "DeepSeek-R1",
      "EntityType": "Foundation",
      "Version": "250120"
    }
  ]
}

所需返回值Result.Sid

2. ListExperienceConversationMessage(获取消息列表)

  • 最小化参数: 与 CreateExperienceConversation(创建会话)一致
1
2
3
{
  "ConversationId": "[上一步的 Result.Sid]"
}

所需返回值Result.Relations[0].SessionId

3. PullExperienceMessage(获取消息流)

对话SSE响应体 正常结束 [DONE]

  • 最小化参数
    • Header中Content-Type需为text/event-stream
    • 这里不必须X-Csrf-Token,不知道为什么,加上最好
  • 响应格式类似OpenAI的SSE格式(但不完全是)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
{
  "SessionId": "ListExperienceConversationMessage的SessionId",
  "Type": "external",
  "MessageList": [
          {
        "Sid": "exms-1",
        // Sid构建组合详见Python生成示例
        "SessionId": "exs-Nekohy",
        "ParentMessageId": "",
        "ContentType": "text",
        "Content": "我是Nekohy",
        "AuthorRole": "user", // 可以是 user 或 assistant 或 system,以下类推
        "ChildMessageIds": [
          "exms-100",
          "exms-107",
          "exms-102",
          "exms-101"
        ], // 没啥必要留着,和下面的DeleteTime一起删了就行,当前Session之前删除过的对话
        "ErrorCode": ""
      },
      {
        "Sid": "exms-2",
        "SessionId": "exs-Nekohy",
        "ParentMessageId": "exms-1", // 字面意思,上一个的对话Sid
        "ContentType": "text",
        "Content": "好的",
        "DeleteTime": 4, // 已删除的次数,和ChildMessageIds的元素数量一致
        "AuthorRole": "assistant",
        "ErrorCode": ""
      },
      {
        "Sid": "exms-3",
        "SessionId": "exs-Nekohy",
        "ParentMessageId": "exms-2",
        "ContentType": "text",
        "Content": "很高兴认识你",
        "AuthorRole": "user",
        "ErrorCode": ""
      },
      {
        "Sid": "exms-4",
        "SessionId": "exs-Nekohy",
        "ParentMessageId": "exms-3",
        "ContentType": "text",
        "Content": "", // 必须留空
        "DeleteTime": 2,
        "AuthorRole": "assistant", // 必须为assistant,最后一个大抵是只能这样
        "ErrorCode": ""
      }
  ],
  "ContextId": 0,
  "UserSetting": [
    {
      "Type": "Int",
      "Name": "max_tokens",
      "DisplayName": "",
      "Min": "0",
      "Max": "8192",
      "DefaultValue": "4096"
    }
  ],
  "Rebuild": true
}

EXMS ID 生成(Python示例)

1
2
3
4
5
6
from nanoid import generate
from datetime import datetime

def generate_exms_id() -> str:
    nano_id = generate(size=22)
    return f"exms-{datetime.now().strftime('%Y%m%d%H%M')}-[{nano_id}]"

格式规则

1
exms-[YYYYMMDDHHmm]-[nanoid(22位)]

其他可选Cookie参数(已知数据)

  • isIntranet=0
  • hasUserBehavior=1
  • AccountID=当前账号ID
  • user_locale=zh
  • signin_i18next=zh
  • monitor_session_id_flag=1
Licensed under CC BY-NC-SA 4.0
这里也许没有你想要的东西...?