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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31042219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:23:22  来源:igfitidea点击:

How do I get authentication in a telegram bot?

pythonauthenticationtelegramtelegram-bot

提问by Kim Stacks

Telegram Bots are ready now.

Telegram Bots 现已准备就绪。

If we use the analogy of web browser and websites, the telegram client applications are like the browser clients.

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

The Telegram Chatrooms are like websites.

Telegram 聊天室就像网站。

Suppose we have some information we only want to restrict to certain users, on the websites, we will have authentication.

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

How do we achieve the same effect on the Telegram Bots?

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

I was told that I can use deep linking. See description here

有人告诉我,我可以使用深层链接。请参阅此处的说明

I will reproduce it below:

我将在下面重现它:

  1. Create a bot with a suitable username, e.g. @ExampleComBot
  2. Set up a webhook for incoming messages
  3. Generate a random string of a sufficient length, e.g. $memcache_key = "vCH1vGWJxfSeofSAs0K5PA"
  4. Put the value 123 with the key $memcache_key into Memcache for 3600 seconds (one hour)
  5. Show our user the button https://telegram.me/ExampleComBot?start=vCH1vGWJxfSeofSAs0K5PA
  6. Configure the webhook processor to query Memcached with the parameter that is passed in incoming messages beginning with /start. If the key exists, record the chat_id passed to the webhook as telegram_chat_id for the user 123. Remove the key from Memcache.
  7. Now when we want to send a notification to the user 123, check if they have the field telegram_chat_id. If yes, use the sendMessage method in the Bot API to send them a message in Telegram.
  1. 使用合适的用户名创建一个机器人,例如@ExampleComBot
  2. 为传入消息设置 webhook
  3. 生成足够长度的随机字符串,例如 $memcache_key = "vCH1vGWJxfSeofSAs0K5PA"
  4. 将键为 $memcache_key 的值 123 放入 Memcache 360​​0 秒(一小时)
  5. 向我们的用户显示按钮https://telegram.me/ExampleComBot?start=vCH1vGWJxfSeofSAs0K5PA
  6. 将 webhook 处理器配置为使用传入消息中以 /start 开头的参数查询 Memcached。如果密钥存在,将传递给 webhook 的 chat_id 记录为用户 123 的 telegram_chat_id。从 Memcache 中删除密钥。
  7. 现在,当我们想向用户 123 发送通知时,请检查他们是否有字段 telegram_chat_id。如果是,请使用 Bot API 中的 sendMessage 方法在 Telegram 中向他们发送消息。

I know how to do step 1.

我知道如何做第 1 步。

I want to understand the rest.

我想了解其余的。

This is the image I have in mind when I try to decipher step 2.

这是我在尝试破译第 2 步时想到的图像。

Enter image description here

在此处输入图片说明

So the various telegram clients communicate with the Telegram Server when talking to ExampleBot on their applications. The communication is two-way.

因此,当在其应用程序上与 ExampleBot 交谈时,各种电报客户端与电报服务器进行通信。沟通是双向的。

Step 2 suggests that the Telegram Server will update the ExampleBot Server via a webhook. A webhook is just a URL.

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

So far, am I correct?

到目前为止,我说得对吗?

What's the next step towards using this for authentication?

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

回答by Vahid Mafi

You are correct so far.

到目前为止你是正确的。

However, your requirements are a bit vague. Let's look at it in another way. If you want to send restricted information to special users, you should ask user to start a direct chat with your bot or simply use users chat_id in groupchat to start sending message to them.

但是,您的要求有点模糊。让我们换个角度来看。如果您想向特殊用户发送受限信息,您应该要求用户开始与您的机器人直接聊天,或者只需在群聊中使用用户 chat_id 开始向他们发送消息。

Please note that you will have access to user chat_id only when the user communicates with the bot in "privacy mode" which is default mode for bots.

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

回答by Pete

Update: I created a GitHub repository with a very simple PHP application to illustrate the concept explained below:

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

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

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



Whether you use a webhook or not is irrelevant.The "deep linking" explained:

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

  1. Let the user log in on an actual website with actual username-password authentication.
  2. Generate a unique hashcode (we will call it unique_code)
  3. Save unique_code->username to a database or key-value storage.
  4. Show the user the URL https://telegram.me/YOURBOTNAME?start=unique_code
  5. Now as soon as the user opens this URL in Telegram and presses 'Start', your bot will receive a text message containing '/start unique_code', where unique_code is of course replaced by the actual hashcode.
  6. Let the bot retrieve the username by querying the database or key-value storage for unique_code.
  7. Save chat_id->username to a database or key-value storage.
  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. 让机器人通过查询数据库或键值存储的 unique_code 来检索用户名。
  7. 将 chat_id->username 保存到数据库或键值存储。

Now when your bot receives another message, it can query message.chat.id in the database to check if the message is from this specific user. (And handle accordingly)

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

Some code (using pyTelegramBotAPI):

一些代码(使用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)

Note: the unique_code will not be shown as '/start unique_code', only '/start', in the Telegram client, but your bot will still receive '/start unique_code'.

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

回答by Juan Madurga

I have just implemented an authentication solutionusing deep linking for Django.

我刚刚使用深度链接为Django实现了一个身份验证解决方案

This solution generates authentication tokens to associate Telegram chats and Django users. When some telegram user wants to access to restricted area it receives a telegram message with a link to login into the web. One logged web site provides a link to start a new authenticated chat using deep linking.

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

Also there is a demofor a polls example which only the logged in user can't vote through a telegram.

还有一个投票示例的演示,只有登录用户不能通过电报投票。

回答by Groosha

As of February 2018 you can use Telegram Login Widgetto authorize people on your website through Telegram.

自 2018 年 2 月起,您可以使用Telegram 登录小工具通过 Telegram 向您网站上的人员授权。