English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french

简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE คนไทย Français русский

回答

收藏

Telegram小程序 启动参数 | 初始数据

开源社区 开源社区 11651 人阅读 | 0 人回复 | 2025-02-20

本帖最后由 riyad 于 2025-2-21 19:52 编辑   g! W$ ^3 l8 g. ]& Y
/ T5 b7 m4 o& b

应用启动参数 列表中,初始化数据位于 tgWebAppData 参数中。 这是一组数据,主要与启动 小应用程序的特定用户有关。

初始数据的一个显著特点是,它可用作身份验证或 授权因素。 因此,不要忘记应用程序 和初始数据的安全性。

检索

要提取初始数据,开发人员可以使用 @telegram-apps/sdk 中的 retrieveLaunchParams 函数。

  1. import { retrieveLaunchParams } from '@telegram-apps/sdk';: S1 _4 N( Y- I/ Q. q6 P8 K

  2. $ }- h; ^! f: S* a6 t3 ?8 r
  3. const { initDataRaw, initData } = retrieveLaunchParams();
复制代码
授权和认证

初始化数据的一个特点是可以用作授权或 身份验证的因素。 事实上,原生 Telegram 应用程序生成的数据会使用 Telegram 机器人的密钥对 进行签名,然后生成的签名会放在 参数本身旁边。

因此,知道了 Telegram 机器人的秘钥,开发者就有机会验证 参数的签名,确保这些参数确实是发给指定用户的。

此外,签名验证操作足够快,不需要大量服务器 资源。

TIP

你可以在这篇文章中找到使用不同编程语言的示例。


5 b: a: V! q" K! \1 Z发送至服务器

为了在服务器上对用户进行授权,开发者需要传输启动小程序时指定的初始化 数据。 开发人员可以在每次向服务器发送请求时传输这些信息,然后在服务器端进行签名验证 。

下面是开发人员向服务器发送初始数据的方法:

  1. import { retrieveLaunchParams } from '@telegram-apps/sdk';
    : J0 Y" S* [: X% G6 G
  2. 8 o3 }1 k, ^% ?; q! o
  3. const { initDataRaw } = retrieveLaunchParams();% w* J9 ~/ Q  p2 V7 K$ G

  4. , w: U) r5 u. ?/ z5 q- g/ g  e
  5. fetch('https://example.com/api', {0 [4 g# b$ h7 X: w8 ~  ~
  6.   method: 'POST',: r" r/ ]: I+ r
  7.   headers: {
    9 b' g- N3 v, s& u" A8 V( x, w
  8.     Authorization: `tma ${initDataRaw}`
    ! \* ?6 ^% n  r4 a- a
  9.   },! b8 T: n" J/ U& {( k
  10. });
复制代码

反过来,服务器端必须执行以下操作:

  • 获取 Authorization(授权)标头的值;
  • 检查其第一部分是否等于 tma;
  • 获取初始数据并 验证 其签名。
    0 }. w1 ?; W) _  S- m" u

如果该算法成功,应用程序的服务器部分就可以信任传输的 初始数据。

验证

初始数据验证是客户端和服务器之间通信 中最重要的部分之一。 它的有效性保证了初始数据可以被信任 并在未来的代码执行中使用。

要知道,初始数据是以查询参数列表的形式呈现的,要验证 ,开发人员应遵循以下步骤:

  • 遍历所有键值对,并以 格式创建字符串值数组 {key}={value}。 hash 应排除在外,但要记下来。 代表初始数据符号,将用于验证过程的最后一步。
  • 将计算出的数组按字母顺序排序。
  • 使用密钥 WebAppData 创建 HMAC-SHA256,并将其应用于绑定到迷你应用程序的 Telegram Bot 令牌。
  • 使用第 3 步的结果作为密钥创建 HMAC-SHA256。 将 应用于第 2 步 中收到的带换行符(\n)的成对数组,并将结果显示为十六进制符号序列。
  • 将第 1 步收到的 hash 值与第 4 步的结果进行比较。
  • 如果这些值相等,则传递的初始数据是可信的。
    * p: ^1 U1 N' D8 {# m4 H6 n
& ]$ H- h1 i* ]2 l. F! W

TIP

在实际应用中,建议使用其他机制来验证 初始化数据。 例如,添加到期日期。 这种检查可以通过 auth_date参数来实现,该参数负责参数创建的日期。 该 解决方案可在初始化数据被盗的情况下,防止 攻击者不断使用这些数据。

TIP

为避免初始数据验证过程中可能出现的问题,我们建议使用 成熟且经过 测试的软件包:


, s* i2 G9 R* q+ g; D% A2 f示例

让我们想象一下,我们有这样的输入:

  1. Telegram Bot token:1 M7 m) A: j" g# s
  2. 5768337691:AAGDAe6rjxu1cUgxK4BizYi--Utc3J9v5AU
    7 H8 G6 _( n! s

  3. $ @' u2 z9 C& g1 g, I
  4. Init data:, l) @; u, ?6 p) ?* z
  5. user=%7B%22id%22%3A279058397%2C%22first_name%22%3A%22Vladislav%22%2C%22last_name%22%3A%22Kibenko%22%2C%22username%22%3A%22vdkfrost%22%2C%22language_code%22%3A%22en%22%2C%22is_premium%22%3Atrue%2C%22allows_write_to_pm%22%3Atrue%7D
    6 F+ x& O7 A. c3 [! W' D4 u1 w0 J
  6. &chat_instance=-3788475317572404878
    , W  q" Y8 Z- n' h# k, W# t1 \
  7. &chat_type=private- P2 d) c# ^" W7 m; a) {  b5 O& X
  8. &auth_date=1709144340
    1 A1 N7 }6 \9 B/ r* G- t
  9. &hash=371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827
复制代码
完成第 1 步和第 2 步后,我们将收到以下数据:1 h0 j8 B  h9 I6 v( z
- |: O. w3 |) H+ P
  1. // Sorted pairs.( ~  C' H( q4 o& D
  2. [" A! d- w2 g  ]$ [% Y+ I
  3.   'auth_date=1709144340',) V: c* z- B0 V, ?
  4.   'chat_instance=-3788475317572404878',# m4 A0 m. \3 a; |9 f8 h  `
  5.   'chat_type=private',
    6 a( {: n* O4 d6 s. q0 s6 f: q/ k
  6.   'user={"id":279058397,"first_name":"Vladislav","last_name":"Kibenko","username":"vdkfrost","language_code":"en","is_premium":true,"allows_write_to_pm":true}'
    . Y" w% J8 M3 `  _/ I# f
  7. ]( h2 L. |& t) y$ L

  8. 3 P& C3 E" }8 A1 d
  9. // Hash.
    - X6 ?+ R/ {  R/ v
  10. '371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827'
复制代码
然后,创建第 3 步所需的 HMAC-SHA256。 它应基于 WebAppData 字面字符串值和 Telegram Bot token。
, K2 {7 }8 U, v7 p& t4 P1 a
  1. HMAC-SHA256(
    ' \5 g2 [$ a- b* M3 w* s! y
  2.   "WebAppData", : x# q9 I& h4 C8 U8 s: k# T6 F
  3.   "5768337691:AAGDAe6rjxu1cUgxK4BizYi--Utc3J9v5AU"% n1 j" [" y) [
  4. ) = "aa492a44bdf019c759defb1698c1d77690189973945491a756051cdc1207a449"
复制代码
最后,让我们使用 第 2 步收到的排序对和第 3 步的值来计算初始数据符号:
( Q5 g8 t& ]1 |) X
  1. joined_pairs =
    ) j. ^& X, A( _( U
  2.    "auth_date=1709144340
    % R/ w6 W' h5 M7 g
  3.    chat_instance=-3788475317572404878: u. G( x3 ~) }4 y2 }; A
  4.    chat_type=private
    7 {- m4 c9 \9 @* w# W9 p4 a
  5.    user={"id":279058397,"first_name":"Vladislav","last_name":"Kibenko","username":"vdkfrost","language_code":"en","is_premium":true,"allows_write_to_pm":true}"* m3 Q2 i1 S* B$ G7 O) {# f& ~& d
  6. 9 S' D* F/ r8 k" C" L
  7. HMAC-SHA256(; S. C! B7 J: t3 }+ G3 P/ u
  8.   "aa492a44bdf019c759defb1698c1d77690189973945491a756051cdc1207a449",
    7 T, Y# |' E' I) `# O! l7 Y& u
  9.   joined_pairs,# C! _- W* g, `2 v
  10. ) = "371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827"
复制代码
现在,将最后收到的结果与第 1 步中的 hash 值进行比较,我们可以看到它们是相等的。 这意味着,我们可以信任传递的初始数据。, r$ s7 R2 ]# G! t2 w$ N$ K

: C; k3 }1 m0 r( }8 l" u4 S可以查看参数列表
& ?$ W- U8 J4 S! ^% ?" G; K: I/ r
! P; V8 n' N# |6 x) n
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则