本帖最后由 riyad 于 2025-2-21 19:52 编辑 - d4 p3 p5 Z+ g( o' l/ ?
+ o+ j, \. R; ^
在应用启动参数 列表中,初始化数据位于 tgWebAppData 参数中。 这是一组数据,主要与启动 小应用程序的特定用户有关。 初始数据的一个显著特点是,它可用作身份验证或 授权因素。 因此,不要忘记应用程序 和初始数据的安全性。 检索要提取初始数据,开发人员可以使用 @telegram-apps/sdk 中的 retrieveLaunchParams 函数。 - import { retrieveLaunchParams } from '@telegram-apps/sdk';, r9 }8 w# s: c1 P5 W6 T* l1 l) F* [9 Y
- ! s: f6 `7 Y6 ^ P1 ^
- const { initDataRaw, initData } = retrieveLaunchParams();
复制代码 授权和认证初始化数据的一个特点是可以用作授权或 身份验证的因素。 事实上,原生 Telegram 应用程序生成的数据会使用 Telegram 机器人的密钥对 进行签名,然后生成的签名会放在 参数本身旁边。 因此,知道了 Telegram 机器人的秘钥,开发者就有机会验证 参数的签名,确保这些参数确实是发给指定用户的。 此外,签名验证操作足够快,不需要大量服务器 资源。 TIP 你可以在这篇文章中找到使用不同编程语言的示例。
+ y. m, D: r) F+ M: g发送至服务器为了在服务器上对用户进行授权,开发者需要传输启动小程序时指定的初始化 数据。 开发人员可以在每次向服务器发送请求时传输这些信息,然后在服务器端进行签名验证 。 下面是开发人员向服务器发送初始数据的方法: - import { retrieveLaunchParams } from '@telegram-apps/sdk';
6 v! t6 o% R% `; ?& q1 t - & [$ A6 K1 z0 b, F! E
- const { initDataRaw } = retrieveLaunchParams();8 V: o8 L. e& q+ u% F7 d+ A7 T
- ; y2 x6 x8 y# Y
- fetch('https://example.com/api', {
5 t2 O5 f4 N; ?8 n$ o - method: 'POST',
]; [" ?6 I/ u* ? - headers: {
; |0 G# @ Q' n7 Z3 |- ]1 ~1 T - Authorization: `tma ${initDataRaw}`5 l: s) D' |& o/ F8 J P
- },, M( ^4 F& {4 A, o2 h' B2 U( X8 ] F
- });
复制代码反过来,服务器端必须执行以下操作: - 获取 Authorization(授权)标头的值;
- 检查其第一部分是否等于 tma;
- 获取初始数据并 验证 其签名。
* d1 u' w' y. v' C# G2 D& u
如果该算法成功,应用程序的服务器部分就可以信任传输的 初始数据。 验证初始数据验证是客户端和服务器之间通信 中最重要的部分之一。 它的有效性保证了初始数据可以被信任 并在未来的代码执行中使用。 要知道,初始数据是以查询参数列表的形式呈现的,要验证 ,开发人员应遵循以下步骤: - 遍历所有键值对,并以 格式创建字符串值数组 {key}={value}。 hash 应排除在外,但要记下来。 代表初始数据符号,将用于验证过程的最后一步。
- 将计算出的数组按字母顺序排序。
- 使用密钥 WebAppData 创建 HMAC-SHA256,并将其应用于绑定到迷你应用程序的 Telegram Bot 令牌。
- 使用第 3 步的结果作为密钥创建 HMAC-SHA256。 将 应用于第 2 步 中收到的带换行符(\n)的成对数组,并将结果显示为十六进制符号序列。
- 将第 1 步收到的 hash 值与第 4 步的结果进行比较。
- 如果这些值相等,则传递的初始数据是可信的。
; s0 R7 d$ [* J9 |/ ^5 u
- F0 v( k" V# `( w2 n4 f* s! O. ETIP 在实际应用中,建议使用其他机制来验证 初始化数据。 例如,添加到期日期。 这种检查可以通过 auth_date参数来实现,该参数负责参数创建的日期。 该 解决方案可在初始化数据被盗的情况下,防止 攻击者不断使用这些数据。 TIP 为避免初始数据验证过程中可能出现的问题,我们建议使用 成熟且经过 测试的软件包:
z' u+ y! ^ V d& g6 W示例让我们想象一下,我们有这样的输入: - Telegram Bot token:0 C2 n! ?1 ^9 G+ w8 G1 g
- 5768337691:AAGDAe6rjxu1cUgxK4BizYi--Utc3J9v5AU% l, {7 f& e3 \) c7 y; K
" F, f7 P8 }# F$ E' Z- Init data:
8 }; @: Z, h# J$ @. U1 G - 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
) Z/ Y- h: n8 n0 [$ Q - &chat_instance=-37884753175724048782 ^2 F% I, O9 R f
- &chat_type=private
$ G# G. ] |5 `3 N - &auth_date=1709144340
3 p ~( z# T- D1 z% b$ ` - &hash=371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827
复制代码 完成第 1 步和第 2 步后,我们将收到以下数据:! y' m0 `- {4 s6 D
2 Q1 ]6 b8 t: N% i
- // Sorted pairs.
5 k8 i- k/ B+ q9 M; h8 d/ S - [- V' ^; M+ Y3 J5 }& N( o# F* o
- 'auth_date=1709144340',
+ h0 e( B+ |6 Y0 ^ - 'chat_instance=-3788475317572404878',
- I7 \8 A; @8 D1 w1 W9 @ - 'chat_type=private',% W) `# T' n" Y2 r
- 'user={"id":279058397,"first_name":"Vladislav","last_name":"Kibenko","username":"vdkfrost","language_code":"en","is_premium":true,"allows_write_to_pm":true}'2 @. ~$ Z) W) a) L
- ]* N6 ]: w, U" b+ Z# `4 C% r7 g
- 6 e% e: A. z" c/ y4 I9 L$ R
- // Hash.# P! A+ |& o2 z+ ~
- '371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827'
复制代码 然后,创建第 3 步所需的 HMAC-SHA256。 它应基于 WebAppData 字面字符串值和 Telegram Bot token。; ^" p) n- p9 K4 L0 R1 a- A
- HMAC-SHA256(. e, g3 t. { C1 I7 `! G4 o- y% S
- "WebAppData", 1 q0 n+ Q% u2 ?/ m
- "5768337691:AAGDAe6rjxu1cUgxK4BizYi--Utc3J9v5AU"
$ X2 R2 g6 ~" E( H2 a( H - ) = "aa492a44bdf019c759defb1698c1d77690189973945491a756051cdc1207a449"
复制代码 最后,让我们使用 第 2 步收到的排序对和第 3 步的值来计算初始数据符号:7 l3 @. ?% P9 J2 c# x: E9 o
- joined_pairs =. X7 J4 j9 j" ^* b
- "auth_date=1709144340$ ~/ X1 Z. R2 K* u
- chat_instance=-3788475317572404878
& g- X+ s7 ~1 q$ f - chat_type=private
0 O& w% B$ h3 v; { - user={"id":279058397,"first_name":"Vladislav","last_name":"Kibenko","username":"vdkfrost","language_code":"en","is_premium":true,"allows_write_to_pm":true}") p+ V, R: Q( Y, i _( b9 S
- ! N) }! L2 V1 O9 B# U
- HMAC-SHA256(' F, W! V: [0 B8 t$ w5 m; O- m
- "aa492a44bdf019c759defb1698c1d77690189973945491a756051cdc1207a449",1 V- R# h$ `: T4 O% F0 z; V% A
- joined_pairs,7 A2 o. s* P1 s* J/ l% W
- ) = "371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827"
复制代码 现在,将最后收到的结果与第 1 步中的 hash 值进行比较,我们可以看到它们是相等的。 这意味着,我们可以信任传递的初始数据。+ y3 g* t1 o- \ |' @: l+ J6 f
4 e. Z$ Y- `1 r$ u7 ]! A可以查看参数列表 。
1 l j0 ^( {+ N" u- G' c
4 `# @/ u: Y' ^" ^; l X, | |