web-dev-qa-db-ja.com

テレグラムボット-OAuth認証

ボットにTwitchAPIによるOAuth認証を実装したいのですが、より良い解決策を探していたときに、この@GitHubBotを見つけました。このボットでは、integrations.telegram.orgから始まるリダイレクトURLを見つけました。/github、そして私はこのような認証を実装する方法を疑問に思います。よろしければ、テレグラムボットにOAuthを実装するためのベストプラクティスを教えていただけますか?より良いケース:認証コードまたは暗黙の付与?
前もって感謝します!

13
Max Max

Telegramを介してサードパーティのサービスへのアクセスを許可するという同じ考えがあり、2つの主要な考えがありました。説明に触発された ディープリンクの使用法

  • 最初のアイデアは、一意のリダイレクトURIを使用して一意の認証URLを作成することでした。残念ながら、Googleコンソールで認証情報を設定するときにリダイレクトURIについての説明を見逃しました。それは言う

「承認されたリダイレクトURIWebサーバーからのリクエストで使用します。これは、ユーザーがGoogleで認証された後にリダイレクトされる、アプリケーション内のパスです。パスには、アクセス用の承認コードが追加されます。プロトコルが必要です。できません。 URLフラグメントまたは相対パスが含まれています。パブリックIPアドレスにすることはできません。」

したがって、このアプローチの動的な一意のリダイレクトURIは、物乞いからの失敗でした。

  • 2つ目は、リソースへのアクセスを取得し、その後、ハッシュ化された認証結果をボットに直接送信することでした。次のようになります。ttps://telegram.me/bot?hashed_code = codeしかし、残念ながら、これも計画どおりに機能しないことがわかりました。私はその事実に本当に失望しましたが、いくつかのこっそりと回り込んだ後、直接URLを介してボットにパラメーターを渡す唯一の方法は/ startコマンドであることがわかりました!

@BotSupportは私の仮定を確認しました:

JV、[17.09.1622:16]サードパーティサービスでユーザーを承認する必要があります。たとえば、Googleカレンダー。そこで、サービスサインインにリダイレクトする単純なURIを作成し、token\authCodeを使用してURLをサーバーにリダイレクトすることにしました。 oauthがユーザーを認証しない限り、リソースへのアクセスを正確に許可したユーザーを特定する必要があります。次の論理的な手順は、受信したトークンをハッシュして、ttps経由でユーザーに送り返すことでした。 //telegram.me/BOT?code=xxx/codeのcommandHandlerがあり、/ codeがボットコマンドリストにある場合、ボットとの会話を開き、このハッシュされたコードをWebhook経由でに送り返すことができると確信しました。アクセス許可ステップで誰が正確に誰であるかを検出するためのサーバー。最後のステップで計画が台無しになっていることに気付いたとき、私はショックを受けました。私が見る限り、/ startコマンドしかトリガーできませんでした。私の質問は:/ startコマンドのみがURLを介してパラメーターを照会できることを確認できますか?その場合、ユーザーを認証および認証する正しい方法についてアドバイスをいただけますか?

ボットサポート、[20.09.16 01:50]こんにちは、お待たせしました。あなたはディープリンク( https://core.telegram.org/bots#deep-linking )について話していて、実際、そこで使用できるのは/ startと/ startgroupだけです。

結局、ユーザーの承認と識別を成功させることができましたが、[〜#〜] start [〜#〜]を見るのは非常に奇妙に見えます)会話の途中にあるボタン。

再開:ttps://telegram.me/youtubeまたはttps://telegram.me/で行われているようにサイレント認証を実行することは許可されていませんGitHubBotですが、サイレントの「十分に近い」バージョンを実行できますoauth承認

注:今のところ、ボットがどのように実装されているかを正確に知ることは困難です(youtube、GitHubBot)が、これにはいくつかのユニークなバックドアがあるはずです同じスキームでttps://integrations.telegram.org/youtube/oauth_redirectにリダイレクトされたボット(少なくとも、oauthサービスからのリダイレクトURIには、ユーザーを識別するための一意の情報が含まれていません)この投稿で説明した場合と同じように)たぶん、何らかのパラメータを使用して認証URLを一意にする方法がいくつかありますが、私が知る限り、それは許可されていません。

スキーム実装の手順:

  1. Webhookを設定する
  2. Oauth_cbエンドポイントを追加します
  3. たとえば、Googleコンソールでアプリの認証情報を取得します
  4. Oauth_cbend_pointへのコールバックを待つ
  5. 手順4の認証コードのハッシュを作成します
  6. ハッシュとauth_codeをキーと値のペアとして保存します
  7. 5からのハッシュでボットにリダイレクトするURLを作成します
  8. 7からのリダイレクトURLを含むHTMLを生成します
  9. パラメータを使用して、ボットへの実際のリダイレクトを8にします
  10. インラインパラメーターを期待する/ startコマンドのパーサーを記述します
  11. / startコマンドでwebhookを待つ
  12. 6からのキーと値のペアでユーザーを識別します
  13. キーと値のペアを削除します
  14. あなたは素晴らしいです!これで、一部のユーザーデータにアクセスできるようになりました

申し訳ありませんが、評判がない限り、画像やリンクはありません

9
evasyuk

テレグラムディープリンク および AWS API Gateway サービスでこれを解決しました。

認証シナリオは次のようになります。

  1. ボットは、サービスへのリンクを開いてサインインするようにユーザーに指示します
  2. サービスは、設定したURLにリダイレクトします。つまり、OAuthコードをcodeパラメータとして含むURLにリクエストを送信します

ボットでそのコードを受け取る必要がありますが、ボットが受け入れるパラメータはstartのみであるため、ボットのURLにリダイレクトすることはできません。これは@evasyukの回答で詳しく説明されています。

私の解決策は、サービスから認証コードを含むコールバックを受信し、それをstartパラメーターを使用してボットのリンクにリダイレクトするAWSAPIGatewayエンドポイントをセットアップすることです。これを行うための基本的な手順は次のとおりです。

AWSアカウントをお持ちだと思いますが、そうでない場合は簡単に作成でき、このソリューションを1年間無料で使用できます。

API Gatewayの無料利用枠には、最大12か月間毎月100万回のAPI呼び出しが含まれます。

  1. コンソールに移動して 新しいAPIゲートウェイを作成 。新しいものを作成して手順に従うか、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"
    
  2. アクション>APIをデプロイし、ステージ名を作成します。関係ありません。

  3. 新しく作成したエンドポイントへのリンクが表示されます。

    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>

通常、ユーザーはTelegramアプリに戻り、スタートボタンを押すように求められます。彼がそうすると、ボットはメッセージを受け取ります/start <auth_code>(ただし、コードはチャット履歴に表示されません)。ボットはこのコードを保存して、ユーザー認証(トークンの取得)に使用できます。

4
laughedelic