电报机器人 - OAuth 授权
Posted
技术标签:
【中文标题】电报机器人 - OAuth 授权【英文标题】:Telegram bot - OAuth authorization 【发布时间】:2016-09-12 21:17:06 【问题描述】:我想在我的机器人上通过 Twitch API 实现 OAuth 授权,当我在寻找更好的解决方案时,我发现了这个 @GitHubBot。在这个以integrations.telegram.org/github 开始的机器人重定向URL 中,我想知道如何实现这样的身份验证。如果你愿意,你能告诉在电报机器人中实施 OAuth 的最佳实践吗?哪种情况更好:授权码还是隐式授权? 提前谢谢!
【问题讨论】:
刚刚意识到它是如何完成的,希望在我有时间的几个小时内详细回答您的问题。 (在 6 个字中:使用 /start 代码重定向到 telegram.me) 【参考方案1】:我有通过 Telegram 授权访问 3rd 方服务的相同想法,我有两个主要想法。 灵感来自解释deep linking usage:
第一个想法是创建具有唯一重定向 URI 的唯一授权 URL。 不幸的是,我在 Google 控制台中设置凭据时错过了有关重定向 URI 的解释。它说"授权的重定向 URI 用于来自 Web 服务器的请求。 这是您的应用程序中用户被重定向到的路径 在他们通过 Google 进行身份验证后。路径将被附加 使用授权码进行访问。必须有协议。不能 包含 URL 片段或相对路径。不能是公网IP 地址。 "
所以,这种方法动态唯一重定向 URI 是一个失败的请求。
第二个是获取资源的访问权限,然后将散列的授权结果直接发送给机器人。 预计看起来像这样: ttps://telegram.me/bot?hashed_code=code 但是,不幸的是,我发现这也无法按计划进行。 我对这个事实感到非常失望,但经过一番偷偷摸摸后,我发现通过直接 URL 将参数传递给机器人的唯一方法是 /start 命令!@BotSupport 证实了我的假设:
JV,[17.09.16 22:16] 我需要在 3rd 方服务中授权用户。 例如,谷歌日历。所以,我决定创建一个简单的 URI 重定向到服务登录并将 URL 重定向到我的服务器 令牌\身份验证码。至于 oauth 不验证用户,我仍然 需要以某种方式确定谁确切授予了访问他的资源的权限。所以 我的下一个合乎逻辑的步骤是散列收到的令牌并将其发送回 用户通过 ttps://telegram.me/BOT?code=xxx 我确信如果 /code 有 commandHandler 并且 /code 在 bot 命令中 列表我将能够与我的机器人打开对话并发送此 通过 webhook 将哈希代码返回到我的服务器以检测谁 正是在访问授权步骤。当我发现时我很震惊 我的计划在最后一步被毁了:据我所知,只有 /start 命令可能会被触发。我的问题是:你能确认 只有 /start 命令可以通过 URL 查询参数?如果是这样,可以 你给我一些关于正确授权方式的建议和 认证用户?
机器人支持,[20.09.16 01:50] 您好,抱歉让您久等了。你在讲话 关于深度链接 (https://core.telegram.org/bots#deep-linking) 和, 实际上,那里只能使用 /start 和 /startgroup。
最后我能够成功执行用户授权\识别,但是在对话中间看到开始按钮看起来很奇怪。
简历:您不能像在 ttps://telegram.me/youtube 或 ttps://telegram.me/GitHubBot 中那样执行静默授权,但您可以执行“关闭足够”版本的静默oauth授权
注意:目前我很难说出这些机器人是如何实现的(youtube、GitHubBot),但它应该是这些机器人的一些独特后门,因为它们重定向到 ttps ://integrations.telegram.org/youtube/oauth_redirect 具有相同的方案(至少,来自 oauth 服务的重定向 URI 不包含唯一信息来识别用户,就像我在这篇文章中描述的那样) 也许,有一种方法可以使用某些参数使 auth URL 唯一,但据我所知,这是不允许的。
方案实施步骤:
-
设置 webhook
添加 oauth_cb 端点
在例如 Google Console 中为您的应用获取凭据
等待回调到 oauth_cb end_point
为第 4 步中的授权代码生成哈希
将 hash 和 auth_code 保存为键值对
使用来自 5 的哈希创建重定向到您的机器人的 URL
生成包含来自 7 的重定向 URL 的 html
使用参数将 8 实际重定向到您的机器人
为需要内联参数的 /start 命令编写解析器
使用 /start 命令等待 webhook
使用来自 6 的键值对识别用户
移除键值对
你太棒了!现在您可以访问一些用户数据了
抱歉,没有图片或链接,就我没有声誉而言
【讨论】:
好的,我发现使用个性化链接的方法是可能的:OAuth RFC 允许您添加自定义唯一参数“状态”,该参数将从授权请求传递到最后。顺便说一句,它是一个强烈推荐的参数,因为它应该是唯一的签名哈希,旨在防止身份验证代码伪造。因此,我使用相同的缓存机制,除了根据用户请求为一个用户个人生成的身份验证 URL。我设法使静默 OAuth 就像使用 YouTube 或 GitHub 机器人完成的一样。希望,我在我的研究中帮助了某人 您好,您能否将您对该流程的实现发布到 github,或者如果您已经完成,请给我一个链接?非常感谢!【参考方案2】:我通过Telegram deep linking 和AWS API Gateway 服务解决了这个问题。
认证场景是这样的:
-
机器人告诉用户打开服务链接并登录
服务重定向到您设置的 URL:即向该 URL 发送请求,其中包含 OAuth 代码作为
code
参数
您需要在您的机器人中接收该代码,但您不能只重定向到您的机器人的 URL,因为它接受的唯一参数是 start
。这在@evasyuk 的回答中有很好的描述。
我的解决方案是设置一个 AWS API Gateway 终端节点,该终端节点将使用来自服务的身份验证代码接收回调,并使用 start
参数将其重定向到您的机器人链接。以下是执行此操作的基本步骤。
我假设您有一个 AWS 账户,但如果没有,它很容易创建,您可以完全免费使用该解决方案一年:
API Gateway 免费套餐包括每月 100 万次 API 调用,最长可达 12 个月。
前往控制台create a new API Gateway。您可以新建一个并按照步骤操作,也可以导入 Swagger 定义(不要忘记更改机器人 URL!):
---
swagger: "2.0"
info:
version: "2017-02-25T14:22:32Z"
title: "BotAuthRedirect"
schemes:
- "https"
paths:
/:
x-amazon-apigateway-any-method:
produces:
- "text/html"
parameters:
- name: "code"
in: "query"
required: false
type: "string"
responses:
200:
description: "200 response"
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
type: "http"
httpMethod: "GET"
passthroughBehavior: "when_no_match"
responses:
default:
statusCode: "200"
requestParameters:
# This is where we map `code` query parameter to `start`
integration.request.querystring.start: "method.request.querystring.code"
# Don't forget to change your bot's username:
uri: "https://telegram.me/my_bot"
definitions:
Empty:
type: "object"
title: "Empty Schema"
按Actions > 部署API,打个艺名,没关系
您将获得新创建的端点的链接,例如
https://<some_id>.execute-api.<region>.amazonaws.com/<stage>
例如
https://abcdefghij.execute-api.eu-central-1.amazonaws.com/auth
你准备好了。现在您可以对您的机器人进行编程,为用户提供服务授权的链接,例如
https://some.service.com/auth?response_type=code&client_id=<your_client_id>&redirect_uri=https://abcdefghij.execute-api.eu-central-1.amazonaws.com
一旦用户关注并登录,他将被发送到
https://abcdefghij.execute-api.eu-central-1.amazonaws.com/auth?code=<auth_code>
将被重定向到
https://telegram.me/my_bot?start=<auth_code>
通常用户会回到他的电报应用程序,在那里他可以按开始按钮。一旦他这样做了,机器人将收到一条消息/start <auth_code>
(但代码不会出现在聊天记录中)。您的机器人可以保存此代码并将其用于用户身份验证(获取令牌)。
【讨论】:
以上是关于电报机器人 - OAuth 授权的主要内容,如果未能解决你的问题,请参考以下文章