如何在电报机器人中获得身份验证?

时间:2015-06-25 05:52:34

标签: python authentication telegram telegram-bot

Telegram Bots现已准备就绪。

如果我们使用网络浏览器和网站的类比,电报客户端应用程序就像浏览器客户端。

电报聊天室就像网站一样。

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

我们如何在Telegram Bots上实现同样的效果?

我被告知我可以使用深层链接。请参阅说明here

我将在下面重现:

  
      
  1. 使用合适的用户名创建机器人,例如@ExampleComBot
  2.   
  3. 为收到的消息设置webhook
  4.   
  5. 生成足够长度的随机字符串,例如$ memcache_key =" vCH1vGWJxfSeofSAs0K5PA"
  6.   
  7. 将带有$ memcache_key键的值123放入Memcache中3600秒(一小时)
  8.   
  9. 向我们的用户显示按钮https://telegram.me/ExampleComBot?start=vCH1vGWJxfSeofSAs0K5PA
  10.   
  11. 将webhook处理器配置为使用以/ start开头的传入消息中传递的参数来查询Memcached。   如果密钥存在,请将传递给webhook的chat_id记录为   用户123的telegram_chat_id。从Memcache中删除密钥。
  12.   
  13. 现在,当我们想要向用户123发送通知时,检查他们是否具有字段telegram_chat_id。如果是,请使用sendMessage   Bot API中的方法在Telegram中向它们发送消息。
  14.   

我知道如何做第1步。

我想了解其余部分。

这是我试图破译第2步时的想法。

Enter image description here

因此,各个电报客户端在与其应用程序的ExampleBot交谈时与Telegram Server进行通信。沟通是双向的。

步骤2建议Telegram Server将通过webhook更新ExampleBot服务器。 webhook只是一个URL。

到目前为止,我是否正确?

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

3 个答案:

答案 0 :(得分:43)

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

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

是否使用webhook 无关紧要。 “深层链接”解释说:

  1. 让用户使用实际的用户名 - 密码身份验证登录实际网站。
  2. 生成唯一的哈希码(我们称之为unique_code)
  3. 将unique_code->用户名保存到数据库或键值存储区。
  4. 向用户显示网址https://telegram.me/YOURBOTNAME?start=unique_code
  5. 现在,一旦用户在Telegram中打开此URL并按下“开始”,您的机器人将收到包含'/ start unique_code'的文本消息,其中unique_code当然被实际的哈希码替换。
  6. 让机器人通过查询unique_code的数据库或键值存储来检索用户名。
  7. 将chat_id->用户名保存到数据库或键值存储区。
  8. 现在,当您的机器人收到另一条消息时,它可以查询数据库中的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)
    

    注意:在电报客户端中,unique_code不会显示为'/ start unique_code',仅显示为'/ start',但您的机器人仍会收到'/ start unique_code'。

答案 1 :(得分:4)

到目前为止你是对的。

但是,您的要求有点模糊。让我们以另一种方式看待它。 如果您想向特殊用户发送受限信息,您应该要求用户开始与您的机器人直接聊天,或者只是在群聊中使用用户chat_id开始向他们发送消息。

请注意,只有当用户以“隐私模式”(机器人的默认模式)与机器人通信时,您才能访问用户chat_id。

答案 2 :(得分:3)

我刚刚使用an authentication solution的深层链接实现了Django

此解决方案生成身份验证令牌以关联Telegram聊天和Django用户。当某些电报用户想要访问受限区域时,它会收到一条电报消息,其中包含登录网络的链接。一个已记录的网站提供了一个链接,可以使用深层链接启动新的经过身份验证的聊天。

此外,还有a demo个民意调查示例,只有登录的用户才能通过电报投票。