本帖最后由 riyad 于 2025-2-21 19:52 编辑
5 }* D) V% j" z. p- l* j$ C* V
- C G* l. D9 A( t4 W3 u在应用启动参数 列表中,初始化数据位于 tgWebAppData 参数中。 这是一组数据,主要与启动 小应用程序的特定用户有关。 初始数据的一个显著特点是,它可用作身份验证或 授权因素。 因此,不要忘记应用程序 和初始数据的安全性。 检索要提取初始数据,开发人员可以使用 @telegram-apps/sdk 中的 retrieveLaunchParams 函数。 - import { retrieveLaunchParams } from '@telegram-apps/sdk';
& Z1 t) \4 c/ J$ T) R! E% X - 0 m, S; R- y# \6 ?/ A, Y/ T8 v" b
- const { initDataRaw, initData } = retrieveLaunchParams();
复制代码 授权和认证初始化数据的一个特点是可以用作授权或 身份验证的因素。 事实上,原生 Telegram 应用程序生成的数据会使用 Telegram 机器人的密钥对 进行签名,然后生成的签名会放在 参数本身旁边。 因此,知道了 Telegram 机器人的秘钥,开发者就有机会验证 参数的签名,确保这些参数确实是发给指定用户的。 此外,签名验证操作足够快,不需要大量服务器 资源。 TIP 你可以在这篇文章中找到使用不同编程语言的示例。
" A7 G8 Q+ \8 ?' T% q$ T* G; L6 U发送至服务器为了在服务器上对用户进行授权,开发者需要传输启动小程序时指定的初始化 数据。 开发人员可以在每次向服务器发送请求时传输这些信息,然后在服务器端进行签名验证 。 下面是开发人员向服务器发送初始数据的方法: - import { retrieveLaunchParams } from '@telegram-apps/sdk';
4 i. u& ^/ Q8 O
2 ^2 ^9 L( I9 V* n/ i% c- const { initDataRaw } = retrieveLaunchParams();
3 q, K+ t8 l( m - s: h$ J) X+ W& `- L% }6 g
- fetch('https://example.com/api', {# n1 B7 b3 Z( u ~
- method: 'POST',4 c+ j6 b7 N0 u7 x- V3 z5 }
- headers: {. p# K1 R, I% c& Y7 R" n6 H% x
- Authorization: `tma ${initDataRaw}`" @6 D3 q; t; P* c- X" Z
- },
% }9 D. q; j7 l1 z: j( |) z, O - });
复制代码反过来,服务器端必须执行以下操作: - 获取 Authorization(授权)标头的值;
- 检查其第一部分是否等于 tma;
- 获取初始数据并 验证 其签名。
& |( k W( S4 g7 [* z$ t
如果该算法成功,应用程序的服务器部分就可以信任传输的 初始数据。 验证初始数据验证是客户端和服务器之间通信 中最重要的部分之一。 它的有效性保证了初始数据可以被信任 并在未来的代码执行中使用。 要知道,初始数据是以查询参数列表的形式呈现的,要验证 ,开发人员应遵循以下步骤: - 遍历所有键值对,并以 格式创建字符串值数组 {key}={value}。 hash 应排除在外,但要记下来。 代表初始数据符号,将用于验证过程的最后一步。
- 将计算出的数组按字母顺序排序。
- 使用密钥 WebAppData 创建 HMAC-SHA256,并将其应用于绑定到迷你应用程序的 Telegram Bot 令牌。
- 使用第 3 步的结果作为密钥创建 HMAC-SHA256。 将 应用于第 2 步 中收到的带换行符(\n)的成对数组,并将结果显示为十六进制符号序列。
- 将第 1 步收到的 hash 值与第 4 步的结果进行比较。
- 如果这些值相等,则传递的初始数据是可信的。
* x0 R- K$ M# f4 n 4 d2 o1 f) Z+ M7 z' x
TIP 在实际应用中,建议使用其他机制来验证 初始化数据。 例如,添加到期日期。 这种检查可以通过 auth_date参数来实现,该参数负责参数创建的日期。 该 解决方案可在初始化数据被盗的情况下,防止 攻击者不断使用这些数据。 TIP 为避免初始数据验证过程中可能出现的问题,我们建议使用 成熟且经过 测试的软件包: " y$ [7 x- R0 g$ ?2 p5 r
示例让我们想象一下,我们有这样的输入: - Telegram Bot token:5 d. M! N# n- u6 u: Z# W+ K2 y
- 5768337691:AAGDAe6rjxu1cUgxK4BizYi--Utc3J9v5AU& b/ I( ]' Q% i4 }6 `' ]5 ]
- 6 s- O! F) P. c! R1 `% J# y0 h$ M
- Init data:, r- F+ U x( @
- 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! C' o6 u# n& G/ ~3 J$ c" J
- &chat_instance=-3788475317572404878
6 |$ M1 O; ~) M& v5 x - &chat_type=private' |& ]3 a6 p" `
- &auth_date=1709144340
' B- T' W( f) I8 x - &hash=371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827
复制代码 完成第 1 步和第 2 步后,我们将收到以下数据:
. M% O7 P* U7 V
8 S) q9 ^$ j2 K, o' _- b! s- // Sorted pairs.) T) u( \ b6 ~- W, @6 Y( P/ R- V v
- [
- Z. R+ e3 w' t3 T9 ~+ V: q. M" |) u - 'auth_date=1709144340',: x" Z4 v7 B" [# _2 L" i
- 'chat_instance=-3788475317572404878',
' g% t4 k, c7 y- b, c - 'chat_type=private',
: \: B' u# T1 x - 'user={"id":279058397,"first_name":"Vladislav","last_name":"Kibenko","username":"vdkfrost","language_code":"en","is_premium":true,"allows_write_to_pm":true}'
- g% t1 G* X$ T& p* D! T - ]) C5 B1 O- s( i9 D, U" A
- # r; J1 z/ \/ ~5 @1 t/ f
- // Hash.
9 y) @+ m4 l' v @ G( d5 @/ W2 z - '371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827'
复制代码 然后,创建第 3 步所需的 HMAC-SHA256。 它应基于 WebAppData 字面字符串值和 Telegram Bot token。
: K# r9 T6 v. r8 v. p- HMAC-SHA256(, v/ w. u$ W+ _0 m
- "WebAppData",
5 K9 Y& {5 L5 ?% c% M - "5768337691:AAGDAe6rjxu1cUgxK4BizYi--Utc3J9v5AU"
) Y2 H& T, J7 K. i T - ) = "aa492a44bdf019c759defb1698c1d77690189973945491a756051cdc1207a449"
复制代码 最后,让我们使用 第 2 步收到的排序对和第 3 步的值来计算初始数据符号:- q, y* j$ A% r' \" K
- joined_pairs =
4 r/ W/ f! [" m+ C# ^ - "auth_date=1709144340
: @# \, \& N9 N+ A- n3 X1 a - chat_instance=-37884753175724048785 V3 o1 a( i0 e5 k( Y
- chat_type=private; F' d6 O" E! M2 m. B
- user={"id":279058397,"first_name":"Vladislav","last_name":"Kibenko","username":"vdkfrost","language_code":"en","is_premium":true,"allows_write_to_pm":true}"
/ {- z' F) j1 Y1 P0 o7 ]
. Q: C* `9 ]5 d- HMAC-SHA256(8 _0 y3 H! r' w' a% l* A# ?+ b3 k
- "aa492a44bdf019c759defb1698c1d77690189973945491a756051cdc1207a449",1 s/ @- v0 Q9 c T! i+ H8 e6 O, Z. y
- joined_pairs,
" v5 N# I- D( l- z - ) = "371697738012ebd26a111ace4aff23ee265596cd64026c8c3677956a85ca1827"
复制代码 现在,将最后收到的结果与第 1 步中的 hash 值进行比较,我们可以看到它们是相等的。 这意味着,我们可以信任传递的初始数据。5 c- T: `% j/ C" n; K' K/ h
3 U& m4 ~2 r1 L9 b
可以查看参数列表 。 I3 s2 R# v9 u3 V4 d
& l+ U0 R+ U' P* s1 e |