Telegram bot - OAuth authorization

不羁岁月 提交于 2020-05-24 21:27:10

问题


I want to implement OAuth authorization by Twitch API on my bot, and when I was looking for a better solution, I found this @GitHubBot. In this bot redirect URL starting for integrations.telegram.org/github, and I wonder how to implement auth like this. If you please, can you tell best practice to implement OAuth in telegram bots? What the better case: Authorization Code or Implicit Grant?
Thank you in advance!


回答1:


I had the same idea of authorizing access to 3rd party services via Telegram and I had 2 main ideas. Inspired by explained deep linking usage:

  • the first idea was to create unique authorization URL with unique redirect URI. Unfortunately, I missed explanation about redirect URIs when was setting up credentials in the Google Console. It says

"Authorized redirect URIs For use with requests from a web server. This is the path in your application that users are redirected to after they have authenticated with Google. The path will be appended with the authorization code for access. Must have a protocol. Cannot contain URL fragments or relative paths. Cannot be a public IP address. "

So, this approach dynamic unique redirect URI was a fail from the begging.

  • the second one was to get access to resources, and after that send hashed authorization result directly to the bot. It was expected to look like this: ttps://telegram.me/bot?hashed_code=code But, unfortunately I found that this also doesn't work as it was planned. I was really disappointing about that fact, but after some sneaking around I found that the only way to pass parameters to your bot through direct URL is /start command!

@BotSupport confirmed my assumptions:

JV, [17.09.16 22:16] I need to authorize user at 3rd party services. For example, Google calendar. So, I decided to create simple URI that redirects to Service Sign In and redirect URL to my server with token\authCode. As far as oauth does not authenticate user, I still need somehow identify who exactly granted access to his resources. So my next logical step was to hash received token and send it back to user via ttps://telegram.me/BOT?code=xxx I was convinced that if there is commandHandler for /code and /code is in the bot commands list I would be able to open conversation with my bot and sent this hashed code via webhook back to my server in order to detect who exactly it was at access grant step. I was shocked when I found that my plan was ruined at the last step: as far as I can see there is only /start command could be triggered. My question is: can you confirm that only /start command could query parameters via URL? if so, could you give me some advise about the right way of authorizing and authenticationg user?

Bot Support, [20.09.16 01:50] Hi, sorry for the wait. You are talking about Deep-linking (https://core.telegram.org/bots#deep-linking) and, indeed, only /start and /startgroup can be used there.

In the end I was able to perform successful user authorization\identification, but it looks very weird to see the START button in the middle of the conversation.

Resume: you are not allowed to perform silent authorization like it's done in ttps://telegram.me/youtube or ttps://telegram.me/GitHubBot, but you could perform "close enough" version of silent oauth authorization

Note: for now it is hard for me to tell how exactly that bots are implemented (youtube, GitHubBot), but it should be some unique backdoor for this bots as far as they redirected to ttps://integrations.telegram.org/youtube/oauth_redirect with the same scheme(at least, redirect URI from oauth service does not contain unique information to identify user just as in case I've described in this post) Maybe, there is a some way of making auth URL unique using some parameter, but as far as I know it is not allowed.

Steps to scheme implementation:

  1. Setup webhook
  2. Add oauth_cb endpoint
  3. Get credentials for your app in, for example, Google Console
  4. Wait for callback to oauth_cb end_point
  5. Make a hash for authorization code from step 4
  6. Save hash and auth_code as key-value pair
  7. Create URL that redirects to your bot with hash from 5
  8. Generate HTML that contains redirection URL from 7
  9. Make actual redirection of 8 to your bot with parameters
  10. Write parser for your /start command that expects in-lined parameters
  11. Wait for webhook with /start command
  12. Identify user with key-value pair from 6
  13. Remove key-value pair
  14. You are awesome! Now you are allowed to accessed some user data

Sorry, no images or links as far as I have no reputation




回答2:


I solved this with Telegram deep linking and AWS API Gateway service.

The authentication scenario is like this:

  1. The bot tells user to open a link to the service and sign in
  2. The service redirects to the URL that you setup: i.e. send a request to that URL with an OAuth code in it as a code parameter

You need to receive that code in your bot, but you cannot just redirect to your bot's URL, because the only parameter it accepts is start. This is well described in @evasyuk's answer.

My solution is to setup an AWS API Gateway endpoint that will receive the callback with the auth code from the service and redirect it to your bot's link with the start parameter. Here are the basic steps to do that.

I assume that you have an AWS account, but if not, it's easy to create and you can use this solution for a year absolutely free:

The API Gateway free tier includes one million API calls per month for up to 12 months.

  1. Head to the console to create a new API Gateway. You can create a new one and follow the steps, or you can import the Swagger definition (don't forget to change the bot 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"
    
  2. Press Actions > Deploy API, make some stage name, it doesn't matter

  3. You will get a link for you newly created endpoint, something like

    https://<some_id>.execute-api.<region>.amazonaws.com/<stage>
    

    For example

    https://abcdefghij.execute-api.eu-central-1.amazonaws.com/auth
    

You are ready to go. Now you can program your bot to give users a link to the service authorization, say

https://some.service.com/auth?response_type=code&client_id=<your_client_id>&redirect_uri=https://abcdefghij.execute-api.eu-central-1.amazonaws.com

Once a user followed it and signed in, he will be sent to

https://abcdefghij.execute-api.eu-central-1.amazonaws.com/auth?code=<auth_code>

which will get redirected to

https://telegram.me/my_bot?start=<auth_code>

and normally user will get back to his Telegram app, where he is offered to press the Start button. Once he did, bot will receive a message /start <auth_code> (but the code won't appear in the chat history). Your bot can save this code and use it for user authentication (getting tokens).



来源:https://stackoverflow.com/questions/37264827/telegram-bot-oauth-authorization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!