本帖最后由 riyad 于 2025-2-21 19:52 编辑
\" {# _( v7 u4 B. I0 G! R1 G9 G! ?( P5 J# f' Y" V
在应用启动参数 列表中,初始化数据位于 tgWebAppData 参数中。 这是一组数据,主要与启动 小应用程序的特定用户有关。 初始数据的一个显著特点是,它可用作身份验证或 授权因素。 因此,不要忘记应用程序 和初始数据的安全性。 检索要提取初始数据,开发人员可以使用 @telegram-apps/sdk 中的 retrieveLaunchParams 函数。 - import { retrieveLaunchParams } from '@telegram-apps/sdk'; f3 {/ O. l" L) G0 }
( Z" V8 d- w2 a" x& _- const { initDataRaw, initData } = retrieveLaunchParams();
复制代码 授权和认证初始化数据的一个特点是可以用作授权或 身份验证的因素。 事实上,原生 Telegram 应用程序生成的数据会使用 Telegram 机器人的密钥对 进行签名,然后生成的签名会放在 参数本身旁边。 因此,知道了 Telegram 机器人的秘钥,开发者就有机会验证 参数的签名,确保这些参数确实是发给指定用户的。 此外,签名验证操作足够快,不需要大量服务器 资源。 TIP 你可以在这篇文章中找到使用不同编程语言的示例。 ; `1 M7 _' }( g H
发送至服务器为了在服务器上对用户进行授权,开发者需要传输启动小程序时指定的初始化 数据。 开发人员可以在每次向服务器发送请求时传输这些信息,然后在服务器端进行签名验证 。 下面是开发人员向服务器发送初始数据的方法: - import { retrieveLaunchParams } from '@telegram-apps/sdk';3 g( G6 D6 ^+ k1 g% V$ ]
$ W% _3 }" I8 ~6 r- l- const { initDataRaw } = retrieveLaunchParams();3 {6 o9 K5 _4 w) i N1 G# M
- ) M/ V$ ]& K) A$ X7 b F( e& T5 S
- fetch('https://example.com/api', { R3 J- e/ ]/ g6 v8 N& R
- method: 'POST',# o2 w2 J7 l& N1 ~) h5 ~
- headers: {1 Z- L k, s+ O9 {- u6 P: c: w4 I
- Authorization: `tma ${initDataRaw}`' `: l0 O% y& k r$ O# j
- },- B5 ]' F, Q" [9 t0 R
- });
复制代码反过来,服务器端必须执行以下操作: - 获取 Authorization(授权)标头的值;
- 检查其第一部分是否等于 tma;
- 获取初始数据并 验证 其签名。) y; C' q9 p' `
如果该算法成功,应用程序的服务器部分就可以信任传输的 初始数据。 验证初始数据验证是客户端和服务器之间通信 中最重要的部分之一。 它的有效性保证了初始数据可以被信任 并在未来的代码执行中使用。 要知道,初始数据是以查询参数列表的形式呈现的,要验证 ,开发人员应遵循以下步骤: - 遍历所有键值对,并以 格式创建字符串值数组 {key}={value}。 hash 应排除在外,但要记下来。 代表初始数据符号,将用于验证过程的最后一步。
- 将计算出的数组按字母顺序排序。
- 使用密钥 WebAppData 创建 HMAC-SHA256,并将其应用于绑定到迷你应用程序的 Telegram Bot 令牌。
- 使用第 3 步的结果作为密钥创建 HMAC-SHA256。 将 应用于第 2 步 中收到的带换行符(\n)的成对数组,并将结果显示为十六进制符号序列。
- 将第 1 步收到的 hash 值与第 4 步的结果进行比较。
- 如果这些值相等,则传递的初始数据是可信的。
6 T( S3 P8 B% D4 m. y6 q$ U5 P
$ ? k, q0 i7 V! T* K5 ITIP 在实际应用中,建议使用其他机制来验证 初始化数据。 例如,添加到期日期。 这种检查可以通过 auth_date参数来实现,该参数负责参数创建的日期。 该 解决方案可在初始化数据被盗的情况下,防止 攻击者不断使用这些数据。 TIP 为避免初始数据验证过程中可能出现的问题,我们建议使用 成熟且经过 测试的软件包: $ S0 J* j% g' W/ w( F9 g: a
示例让我们想象一下,我们有这样的输入: - Telegram Bot token:% ~9 b* J, N. ~: |2 C( m7 |
- 5768337691:AAGDAe6rjxu1cUgxK4BizYi--Utc3J9v5AU( C/ ?9 r! t1 x5 ]0 w% G
% f' H2 |2 M i' u! Q; @1 E- Init data:
; I4 n) h! X3 { - 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 d# H2 l2 @. c2 l' k - &chat_instance=-3788475317572404878
9 |) \: K( B1 f; a" m3 D - &chat_type=private7 L2 k' X! \% Z4 J
- &auth_date=1709144340, ~/ V$ y# R# }2 N& L: h# K
- &hash=371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827
复制代码 完成第 1 步和第 2 步后,我们将收到以下数据:
2 U( c2 I* K! o+ N" s8 ^% o/ x0 m% W8 f6 f! e! i$ N7 ^- g
- // Sorted pairs.
. C6 e* _9 d; ]1 G9 M4 b$ ~' v( k1 b - [9 F5 w% F4 P- }' a; z
- 'auth_date=1709144340',
- d* q4 e& [& d+ ^8 P; ] - 'chat_instance=-3788475317572404878',. t+ |0 M) \& ~1 H' c2 D
- 'chat_type=private',8 l* r! Z) a9 s$ O/ L8 Q/ r
- 'user={"id":279058397,"first_name":"Vladislav","last_name":"Kibenko","username":"vdkfrost","language_code":"en","is_premium":true,"allows_write_to_pm":true}', @! u0 Q) {, v; B: c
- ]
3 k) D$ v! D8 A7 z% K/ h8 C7 j - \' f1 S/ x- d& H1 j2 B6 y
- // Hash.$ u0 G7 n1 `/ u; D7 D9 E
- '371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827'
复制代码 然后,创建第 3 步所需的 HMAC-SHA256。 它应基于 WebAppData 字面字符串值和 Telegram Bot token。1 m/ k0 W% E. q4 z8 v8 \
- HMAC-SHA256(1 v" h; u! \7 I8 v w6 b
- "WebAppData", ! l$ D5 N( C0 q$ y: M
- "5768337691:AAGDAe6rjxu1cUgxK4BizYi--Utc3J9v5AU"6 r! n, r4 X! d
- ) = "aa492a44bdf019c759defb1698c1d77690189973945491a756051cdc1207a449"
复制代码 最后,让我们使用 第 2 步收到的排序对和第 3 步的值来计算初始数据符号:
& Z5 p# M" ]& d0 f9 y# W- joined_pairs =+ y( C E5 }9 T) `
- "auth_date=1709144340
* R- X6 Q0 O; Z$ _! d' p - chat_instance=-3788475317572404878
; g# c; r Z( m - chat_type=private2 ]* D, i& W4 F, W g: X7 T2 k {
- user={"id":279058397,"first_name":"Vladislav","last_name":"Kibenko","username":"vdkfrost","language_code":"en","is_premium":true,"allows_write_to_pm":true}"
" L1 O1 G2 x4 P1 A - 9 A3 }) `0 G/ W
- HMAC-SHA256(* C) N3 f4 c! I6 k n
- "aa492a44bdf019c759defb1698c1d77690189973945491a756051cdc1207a449",( @+ L9 [2 R" ^
- joined_pairs,
! ?7 Z- Y( \; T: A- O - ) = "371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827"
复制代码 现在,将最后收到的结果与第 1 步中的 hash 值进行比较,我们可以看到它们是相等的。 这意味着,我们可以信任传递的初始数据。
0 b* K4 Q: p! `* b% }
6 M4 x- P3 j+ F; e/ N可以查看参数列表 。# W5 w2 z9 a2 _6 P( }9 ]
. g+ R- L7 b P
|