1. 什么是 WebApp.initData

  • 定义WebApp.initData 是 Telegram WebApp SDK 提供的一个字符串,包含用户在 Mini App 环境中的认证信息(URL 编码格式)。
  • 内容:包括 user 对象(JSON 格式,含 idfirst_nameusernameauth_date 等)和 hash(用于验证数据完整性)。
  • 用途:前端获取 WebApp.initData 后,通过调用 /auth/telegram/callback 传递给后端,后端验证签名并完成用户认证。
  • 格式示例user=%7B%22id%22%3A123456789%2C%22first_name%22%3A%22John%22%2C%22username%22%3A%22john_doe%22%2C%22auth_date%22%3A1697059200%2C%22hash%22%3A%22abc123...%22%7D 解码后: json { "user": { "id": 123456789, "first_name": "John", "username": "john_doe", "auth_date": 1697059200, "hash": "abc123..." } }

2. 如何获取 WebApp.initData

获取 WebApp.initData 需要使用 Telegram 的 WebApp SDK,只有在 Telegram Mini App 环境中运行时有效(即通过 @battletgmini_bot 打开的页面)。以下是具体步骤和代码:

2.1 引入 Telegram WebApp SDK

  • 在前端项目中引入 Telegram 的 WebApp SDK。
  • 方法:在 HTML 文件中添加 <script> 标签,或在 JavaScript 模块中导入。
  • 示例(HTML): ```html

- 示例(JavaScript 模块,如 React/Vue):javascript import WebApp from '@twa-dev/sdk'; ```

2.2 初始化 WebApp

  • 调用 WebApp.ready() 确保 SDK 初始化完成。
  • 获取 WebApp.initData: ```javascript import WebApp from '@twa-dev/sdk';

// 初始化 WebApp WebApp.ready();

// 获取 initData const initData = WebApp.initData; console.log('initData:', initData); `` - **说明**: -WebApp.initData是一个字符串,包含 URL 编码的用户数据。 - 如果initData为空,可能是因为代码未在 Telegram Mini App 环境中运行(需通过@battletgmini_bot` 打开页面)。

2.3 检查用户数据(可选)

  • 可通过 WebApp.initDataUnsafe 获取解析后的用户数据(仅用于调试或展示): javascript const user = WebApp.initDataUnsafe.user; console.log('User:', user); // { id: 123456789, first_name: 'John', username: 'john_doe', ... }
  • 注意initDataUnsafe 不应直接用于认证,需将原始 initData 传递给后端,由后端验证签名。

3. 结合授权登录流程调用 WebApp.initData

根据你的 AuthController 和之前的流程,获取 WebApp.initData 后需配合 /auth/telegram/init/auth/telegram/callback 完成静默登录。以下是完整流程和代码:

3.1 流程图(Mini App 静默登录)

[用户打开 Mini App (@battletgmini_bot)]
    ↓
[前端调用 /auth/telegram/init?source=miniapp&inviteCode=xxx] → [后端返回 botUsername, inviteCode]
    ↓
[前端调用 WebApp.ready() 和 WebApp.initData]
    ↓
[前端调用 /auth/telegram/callback, 传 initData, inviteCode] → [后端验证, 返回 JWT token]
    ↓
[前端保存 token, 显示用户界面]

3.2 代码示例

以下是简要的前端代码,展示如何获取 WebApp.initData 并完成登录:

import WebApp from '@twa-dev/sdk';

// 初始化 WebApp
WebApp.ready();

// 步骤 1: 调用 /auth/telegram/init
async function initMiniAppAuth(inviteCode) {
  try {
    const response = await fetch(`https://desigee.vip/auth/telegram/init?source=miniapp&inviteCode=${inviteCode}`);
    const data = await response.json();
    if (data.code !== 200) throw new Error(data.message);
    localStorage.setItem('inviteCode', data.inviteCode);
    return data.botUsername; // @battletgmini_bot
  } catch (error) {
    console.error('Init failed:', error.message);
    throw error;
  }
}

// 步骤 2: 获取 initData 并调用 /auth/telegram/callback
async function handleMiniAppCallback() {
  try {
    const initData = WebApp.initData; // 获取 initData
    if (!initData) throw new Error('initData is empty. Ensure running in Mini App.');
    const inviteCode = localStorage.getItem('inviteCode');
    const response = await fetch('https://desigee.vip/auth/telegram/callback', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ initData, inviteCode })
    });
    const data = await response.json();
    if (data.code !== 200) throw new Error(data.message);
    localStorage.setItem('token', data.data.token);
    console.log('Login success:', data.data.user);
  } catch (error) {
    console.error('Callback failed:', error.message);
    throw error;
  }
}

// 执行登录
async function login() {
  try {
    await initMiniAppAuth('abc12345');
    await handleMiniAppCallback();
  } catch (error) {
    console.error('Login failed:', error.message);
  }
}

// 触发登录
login();

4. 注意事项

  • 环境要求
  • WebApp.initData 仅在 Telegram Mini App 环境中有效(通过 @battletgmini_bot 打开的页面)。
  • 如果在普通浏览器中运行,initData 会为空,导致错误。
  • 测试时,确保通过 Telegram 客户端打开 Mini App(https://t.me/battletgmini_bot)。
  • 调试方法
  • 检查 initData 是否为空: javascript console.log('initData:', WebApp.initData);
  • 如果为空,确认页面是否通过 Mini App 打开,或检查 SDK 引入是否正确。
  • 后端验证
  • 你的 AuthController 已实现 initData 的签名验证(使用 HMAC-SHA256 和 botToken)。
  • 确保 application.yml 配置正确: yaml telegram: bot: id: "@battletgmini_bot" token: "your_new_bot_token" # 更换泄露的 Token domain: https://desigee.vip
  • 安全
  • 立即更换 Bot Token(之前泄露的 8388393478:AAHR5JLBt_UfTLYOJa5v1LyWhIH1TrZiAls),在 @BotFather 生成新 Token。
  • 确保 https://desigee.vip 已配置 SSL(certbot --nginx -d desigee.vip)。
  • 错误处理
  • 如果 /callback 返回 Invalid Telegram data,检查 initData 是否正确传递。
  • 如果返回 AUTH_DATA_EXPIRED,确保 auth_date 在 24 小时内(由后端验证)。

5. Markdown 文档(补充 WebApp.initData 使用说明)

以下是更新后的 Markdown 文档,包含获取 WebApp.initData 的说明,聚焦 Mini App 模式(因为静默登录更常见于你的 @battletgmini_bot)。

# Telegram 授权登录接口文档(Mini App 模式)

**基地址**: `https://desigee.vip`

**认证方式**: 匿名访问,无需 JWT token。

## 获取 WebApp.initData
- **描述**: `WebApp.initData` 是 Telegram Mini App 提供的用户认证数据,用于静默登录。
- **步骤**:
  1. 引入 Telegram WebApp SDK:
     ```html
     <script src="https://telegram.org/js/telegram-web-app.js"></script>
     ```
     或:
     ```javascript
     import WebApp from '@twa-dev/sdk';
     ```
  2. 初始化 WebApp 并获取 `initData`:
     ```javascript
     WebApp.ready();
     const initData = WebApp.initData; // 字符串,如 "user=%7B%22id%22%3A123456789..."
     ```
  3. 确保在 Telegram Mini App 环境中运行(通过 `@battletgmini_bot` 打开)。
- **注意**:
  - `initData` 仅在 Mini App 环境中有效,普通浏览器返回空。
  - 使用 `initData` 调用 `/auth/telegram/callback`,不要直接解析 `WebApp.initDataUnsafe`。

## 1. 初始化 Telegram 认证
- **URL**: `/auth/telegram/init`
- **Method**: `GET`
- **描述**: 初始化 Mini App 登录,返回机器人用户名和邀请码。
- **请求参数**:
  | 参数名     | 类型   | 必填 | 描述             | 示例       |
  |------------|--------|------|------------------|------------|
  | source     | String | 是   | 填 `miniapp`     | `miniapp`  |
  | inviteCode | String | 否   | 邀请码           | `abc12345` |
- **请求示例**:
  ```bash
  GET https://desigee.vip/auth/telegram/init?source=miniapp&inviteCode=abc12345
  ```
- **响应示例**:
  ```json
  { "code": 200, "botUsername": "@battletgmini_bot", "inviteCode": "abc12345" }
  ```
  - 错误: `{ "code": 400, "message": "Invalid source" }`
- **操作步骤**:
  1. 调用接口,传入 `source=miniapp` 和可选 `inviteCode`。
  2. 保存 `inviteCode`(localStorage)。

## 2. Telegram 认证回调
- **URL**: `/auth/telegram/callback`
- **Method**: `POST`
- **描述**: 验证 `initData`,返回 JWT token。
- **请求头**: `Content-Type: application/json`
- **请求体**:
  ```json
  {
    "initData": "user=%7B%22id%22%3A123456789%2C%22first_name%22%3A%22John%22%2C%22auth_date%22%3A1697059200%2C%22hash%22%3A%22abc123...%22%7D",
    "inviteCode": "abc12345"
  }
  ```
- **请求示例**:
  ```javascript
  fetch('https://desigee.vip/auth/telegram/callback', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ initData: WebApp.initData, inviteCode: 'abc12345' })
  })
  ```
- **响应示例**:
  ```json
  {
    "code": 200,
    "data": {
      "token": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "user": { "username": "tg_123456789", "nickName": "John", "sparksBalance": 0 }
    }
  }
  ```
  - 错误: `{ "code": 400, "message": "Invalid Telegram data" }`
- **操作步骤**:
  1. 获取 `WebApp.initData`。
  2. 发送 POST 请求,传入 `initData` 和 `inviteCode`。
  3. 保存 `token`(localStorage)。

## 前端操作流程
1. 引入并初始化 WebApp:
   ```javascript
   import WebApp from '@twa-dev/sdk';
   WebApp.ready();
   ```
2. 调用 `/init`:
   ```javascript
   fetch('https://desigee.vip/auth/telegram/init?source=miniapp&inviteCode=abc12345')
     .then(res => res.json())
     .then(data => localStorage.setItem('inviteCode', data.inviteCode));
   ```
3. 获取 `initData` 并调用 `/callback`:
   ```javascript
   const initData = WebApp.initData;
   fetch('https://desigee.vip/auth/telegram/callback', {
     method: 'POST',
     headers: { 'Content-Type': 'application/json' },
     body: JSON.stringify({ initData, inviteCode: localStorage.getItem('inviteCode') })
   })
     .then(res => res.json())
     .then(data => localStorage.setItem('token', data.data.token));
   ```

6. 最终建议

  • 获取 WebApp.initData
  • 确保在 Mini App 环境中运行(通过 @battletgmini_bot 打开)。
  • 使用 WebApp.ready() 初始化,获取 WebApp.initData
  • 后端配置
  • 验证 application.ymlyaml telegram: bot: id: "@battletgmini_bot" token: "your_new_bot_token" # 更换泄露的 Token domain: https://desigee.vip
  • 确保 https://desigee.vip 已配置 SSL。
  • 测试
  • 在 Telegram 中打开 @battletgmini_bot,测试登录流程。
  • 检查 initData 是否正确传递,验证 /callback 返回的 token