没有默认按钮的电报授权

时间:2019-05-28 18:11:42

标签: javascript reactjs oauth telegram telegram-bot

记录使用第三方电报授权的唯一方法是使用https://core.telegram.org/widgets/login

提供的脚本

这个脚本(正如我所挖掘的)以非常奇怪的方式工作

  1. 它会在iframe内显示“使用电报登录”按钮,并显示另一个额外的script,该按钮可以加载一些要使用的电报实体(例如TWidgetLoginTSticker (?)TVideo (??)TAudio (???)等)。
  2. 通过点击按钮,此iframe打开执行授权的新窗口。
  3. 授权完成后,此窗口将关闭,并且既然完成了,iframe将再次检查授权。如果操作正确,iframe将检索所有共享的用户信息,并取决于授权结束调用data-onauth的类型,或将请求发送到data-auth-url

这种行为对我来说真的是不可用的,因为我们也在附近使用Google,Github和Facebook OAuths,它们都提供了正常可用的API,以手动打开授权窗口并重定向到指定的url。

我的意思是,这就是我们的Google授权的工作方式:

  1. 用户点击由我们自己创建的 按钮,该按钮经过定制以匹配我们的应用程序样式。
  2. 点击后,我们的应用程序将使用网址https://hostname/some/path/to/auth?and_some_params=here创建新窗口
  3. 我们的服务器将其捕获并重定向到Google OAuth同意屏幕。
  4. 完成Google授权后,它将用户重定向到另一个/some/path/to/completed_authorization
  5. 服务器检索所有必要的信息,然后将窗口重定向到具有脚本的/some/path/to/success_authorization的{​​{1}}到具有授权信息的父窗口。
  6. 父窗口(应用程序窗口)捕获此消息,关闭窗口并使用给定的用户数据填充存储空间。

就这样了。由于打开的窗口是由应用程序打开的,因此可以在不使用窗口时对其进行控制和关闭(例如,当打开另一个身份验证窗口或关闭应用程序选项卡时)。

电报中不适合使用“用电报登录”按钮的是:

  1. 无法风格化按钮以匹配应用程序样式
  2. 无法更改按钮的内容(在我们的情况下,因为我们的应用程序是多语言的,所以有必要)。
  3. 无法控制打开的窗口(即使关闭了主窗口也正在打开)

目前,我可以使用“电报OAuth”屏幕打开一个窗口

window.postMessage

但是,由于授权已完成,因此我无法设置任何内容让服务器知道它应该检索用户数据并使用// some code above this.popup = window.open("https://oauth.telegram.org/auth?bot_id=<my_bot_id>&origin=http%3A%2F%2F<mydevorigin>&request_access=write, "authWindow", <some window params>) // some code below 重定向到我的页面

如果没有“使用电报登录”按钮,是否有任何方法可以实现电报授权?我们非常感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

因此,有一种更简便的方法,而无需直接收听postMessages。

电报小部件脚本https://telegram.org/js/telegram-widget.jsTelegram对象添加到窗口,该对象具有Login属性,该属性具有auth功能。

auth函数接受optionscallback,如下所示:

declare const auth: (options: Options, callback: Callback) => void;

interface Options {
  bot_id: string;
  request_access?: boolean;
  lang?: string;
}

interface Data {
  auth_date: number;
  first_name: string;
  hash: string;
  id: number;
  last_name: string;
  username: string;
  // I think there could be other properties too
}

type Callback = (dataOrFalse: Data | false) => void;

请注意,如果授权失败,将使用callback布尔值来调用false

因此,您所需要做的就是加载小部件脚本(没有数据属性,因为否则它将使用按钮初始化iframe),然后在需要时调用此函数:

window.Telegram.Login.auth(
  { bot_id: 'YOUR_BOT_ID', request_access: true },
  (data) => {
    if (!data) {
      // authorization failed
    }

    // Here you would want to validate data like described there https://core.telegram.org/widgets/login#checking-authorization
    doWhateverYouWantWithData(data);
  }
);

auth将打开带有Telegram授权界面的另一个窗口,并且将单独侦听此窗口中的消息。窗口关闭时,您的callback将被调用。

答案 1 :(得分:2)

我看到的是

@Limbo-生成的小部件和代码只是根据我们的漫游器名称和其他参数创建一个内含内容的iframe。每次都一样。 例如,对于(https://oauth.telegram.org/embed/samplebot?origin=https%3A%2F%2Fcore.telegram.org&size=medium&userpic=false),响应中感兴趣的部分在这里:

<div class="tgme_widget_login medium nouserpic" id="widget_login"><button class="btn tgme_widget_login_button" onclick="return TWidgetLogin.auth();"><i class="tgme_widget_login_button_icon"></i>Log in with Telegram</button></div>

<script src="//telegram.org/js/widget-frame.js?27"></script>
<script>TWidgetLogin.init('widget_login', 547043436, {"origin":"https:\/\/core.telegram.org"}, false, "en");

并且每次都相同。因此,您只需将此代码添加到页面中,即可自定义按钮样式,并根据需要放置在页面的任何位置。只需注意id参数,不要忘记为onClick添加一个事件侦听器,当您要显示登录弹出窗口时,该事件侦听器将调用TWidgetLogin.auth()。

TWidgetLogin.init函数接受几个参数(target_login_btn_id,bot_id,params,init_auth,lang)。所有这些都是自我描述。

有趣的部分-关于获取身份验证信息。如果检查widget-frame.js,您将发现在成功通过身份验证后,它将使用数据参数中的用户数据调用window.parent.postMessage(JSON.stringify(data), origin || '*');。在我们的情况下(我们在没有iframe的情况下运行),postMessage将传递到当前窗口,您将可以使用简单的代码捕获它

window.addEventListener("message", function(event) {console.log('get message, evetn)}, false);

及其可在其中获取所需所有用户数据的地方。

唯一的事情-该消息的来源。但是此参数脚本从电报服务器获取用户数据,因此我怀疑它会包含链接的站点来源,而我们对此不会有任何问题。

祝您好运,还有待进一步调查。