如何在Telegram机器人中获得认证?

52

Telegram机器人已准备就绪。

如果我们用浏览器和网站的比喻,Telegram客户端应用程序就像浏览器客户端。

Telegram聊天室则类似于网站。

假设我们有一些信息只想限制给特定用户,在网站上,我们会进行身份验证。

那么如何在Telegram机器人上实现同样的效果呢?

我被告知可以使用深层链接。请参见此处的说明。

我将在下面复制它:

  1. 创建一个适当的用户名为@ExampleComBot的机器人
  2. 设置接收消息的Webhook
  3. 生成一个足够长度的随机字符串,例如$memcache_key =“vCH1vGWJxfSeofSAs0K5PA”
  4. 将键值为$memcache_key,值为123的信息存储到Memcache中,有效期3600秒(一小时)
  5. 向用户展示按钮:https://telegram.me/ExampleComBot?start=vCH1vGWJxfSeofSAs0K5PA
  6. 配置Webhook处理器,使用传入消息中以“/start”开头的参数查询Memcached。如果键存在,则将chat_id记录为telegram_chat_id,并删除该键。
  7. 现在,当我们想向用户123发送通知时,请检查他们是否具有telegraph_chat_id字段。如果是,则使用Bot API中的sendMessage方法向他们发送Telegram消息。

我知道如何执行步骤1。

我想了解接下来的步骤。

这是我在尝试理解步骤2时所想象的图片。

这里输入图片描述

因此,各种 Telegram 客户端在与其应用程序上的 ExampleBot 交流时会与 Telegram 服务器进行通信。通信是双向的。

第二步建议 Telegram 服务器通过 Webhook 更新 ExampleBot 服务器。Webhook 只是一个 URL。

到目前为止,我正确吗?

那么,使用此进行身份验证的下一步是什么?

4个回答

74

更新:我创建了一个 GitHub 存储库,其中包含一个非常简单的 PHP 应用程序,以说明下面解释的概念:

https://github.com/pevdh/telegram-auth-example


无论您是否使用Webhook,实际上并不重要。

所谓“深度链接”解释如下:

  1. 让用户在实际网站上使用实际的用户名密码进行登录认证。
  2. 生成一个唯一的哈希码(我们将其称为unique_code)
  3. 将unique_code->username保存到数据库或键值存储中。
  4. 向用户显示URL https://telegram.me/YOURBOTNAME?start=unique_code
  5. 现在,只要用户在Telegram中打开此URL并按“开始”,您的机器人就会收到包含“/start unique_code”的文本消息,其中unique_code当然被实际的哈希码替换。
  6. 让机器人通过查询数据库或键值存储来检索用户名以获取用户名。
  7. 将chat_id->username保存到数据库或键值存储中。

现在,当您的机器人接收到另一条消息时,它可以在数据库中查询message.chat.id以检查该消息是否来自特定用户。(并相应处理)

一些代码(使用pyTelegramBotAPI):

import telebot
import time

bot = telebot.TeleBot('TOKEN')

def extract_unique_code(text):
    # Extracts the unique_code from the sent /start command.
    return text.split()[1] if len(text.split()) > 1 else None

def in_storage(unique_code): 
    # Should check if a unique code exists in storage
    return True

def get_username_from_storage(unique_code): 
    # Does a query to the storage, retrieving the associated username
    # Should be replaced by a real database-lookup.
    return "ABC" if in_storage(unique_code) else None

def save_chat_id(chat_id, username):
    # Save the chat_id->username to storage
    # Should be replaced by a real database query.
    pass

@bot.message_handler(commands=['start'])
def send_welcome(message):
    unique_code = extract_unique_code(message.text)
    if unique_code: # if the '/start' command contains a unique_code
        username = get_username_from_storage(unique_code)
        if username: # if the username exists in our database
            save_chat_id(message.chat.id, username)
            reply = "Hello {0}, how are you?".format(username)
        else:
            reply = "I have no clue who you are..."
    else:
        reply = "Please visit me via a provided URL from the website."
    bot.reply_to(message, reply)

bot.polling()

while True:
    time.sleep(0)

注意:在 Telegram 客户端中,唯一代码将不会显示为“/start unique_code”,而只会显示为“/start”,但您的机器人仍将收到“/start unique_code”。

1
OP不希望用户通过他们的Telegram应用程序进行通信。因此,这个答案是无关的,因为它依赖于“/start”。 - supermario

6

5
我刚刚使用深度链接实现了身份验证方案,用于Django
该解决方案生成认证令牌以将Telegram聊天和Django用户关联起来。当某个Telegram用户想要访问受限区域时,它会收到一条带有登录网页链接的Telegram消息。已登录的网站提供一个链接,以使用深度链接启动新的经过身份验证的聊天。
此外,还有演示用于投票示例,只有已登录的用户才能通过Telegram进行投票。

有趣。然而,我无法弄清楚如何使用它来验证用户。如果您能提供完整的身份验证示例,我将非常感激。 - supermario

4

到目前为止,你说得没错。

然而,你的要求有点模糊。让我们从另一个角度来看待它。 如果你想向特定用户发送受限信息,你应该要求用户与你的机器人开始直接聊天,或者在群聊中使用用户的聊天ID开始向他们发送消息。

请注意,只有当用户以机器人的“隐私模式”与机器人通信时,你才能访问用户的聊天ID,这是机器人的默认模式。


我在考虑一种用户名和密码认证方式,或者使用6位电话PIN码。 - Kim Stacks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接