自作 GitHub App のインストールをアプリ側のWebからさせて、戻ってこさせて、設定をさせるには。
先週やった GitHub App を作ってみるテストで、ある程度の流れや構造は理解できたとおもうんだけど
作りたいアプリはまず slack アカウントでログインしたあと、そこに紐付ける形で GitHub のリポジトリ群をつなぐ必要がある。ページ遷移もアプリ側からつなげた状態でやりたいのだけど、どうやればいいかわからないので調べます。
調べるとっかかりがわからないのだけど、App の設定で気になったのはこの Callback URL
Request user authorization (OAuth) during installation
にチェックを入れると Callback URL が必須になって、Post installation の helper text がちょっと変わる。
「App インストール中に ユーザ自身の identity アクセスへの許可を求める」ということで、それっぽい。
チェックボックス下の説明リンクを読む。
GitHub のドキュメントってなんでこんなに読むのつらいの。
GitHub Appは、Issueの作成、デプロイメントの作成、サポートされている他のエンドポイントの利用など、アクションをユーザの代わりに行うことができます。
いや、そういうことじゃない。
Web アプリケーションフロー
Web アプリケーションフローを利用して、サイト上のユーザを特定するプロセスは以下の通りです。
- ユーザはGitHubのアイデンティティをリクエストするためにリダイレクトされます
- GitHubによるサイトへのユーザのリダイレクト
- GitHub Appはユーザのアクセストークンで API にアクセスします
ぜんぜんわからん。どこからどこにリダイレクトされるの?どのタイミング?Web アプリケーションフローとかいうジェネリックな名前はなんなんだ。
アプリを作成または変更するときに [インストール時にユーザーの認可 (OAuth) を要求する] を選択すると、アプリのインストール時に手順 1 が完了します。 詳細については、「インストール中のユーザーの認可」を参照してください。
うーん、近そうだけど。。ここでリンク踏むのがいいか、続き読むのがいいかわからんのがつらい。
続きをざっと読むと、普通の Oauth2 による認可プロセスを説明してるっぽいかんじ。
あとデバイスフローとは、もある。これは CLI とかの Web UI がないアプリ用のフローっぽいので今回は関係なし。
ユーザがGitHub App の認可を取り消したときの流れも説明してる。これはあとでちゃんと見ないといけなそう。
ユーザーが GitHub アプリの認可を取り消すと、アプリは既定で github_app_authorization Webhook を受け取ります。 GitHub App は、このイベントをサブスクライブ解除できません。 だれでも、GitHub アカウント設定ページから GitHub アプリの承認を取り消すことができます。 GitHub Appの認可を取り消しても、そのGitHub Appはアンインストールされません。 GitHub Appは、このwebhookを受信したら、トークンを取り返した人の代わりにAPIを呼ぶことを止めるようにプログラムしなければなりません。 取り消されたアクセス トークンを使い続けると、GitHub App は 401 Bad Credentials エラーを受け取ることになります。
インストール済みでも、認可されてる・されてないの管理がいるのか。アンインストールも対応いるけど。
続きの以下の項目はざっとみたけど今回は関係ないっぽい気がする。
- ユーザレベルの権限
- ユーザからサーバーへのリクエスト
戻って「インストール中のユーザの認可」を見る。
インストール中のユーザの認可
認可のプロセスは、アプリケーションのインストール中に完了させることでシンプルにできます。 そのためには、GitHub 上でアプリケーションを作成もしくは変更する際に [インストール中にユーザの認可 (OAuth) をリクエスト] を選択してください。 詳細については、「GitHub アプリの作成」を参照してください。誰かがアプリケーションをインストールしたら、そのユーザのアクセストークンを取得する必要があります。 詳細については、「サイト上のユーザーを特定する」の手順 2 と 3 を参照してください。
とても近い。
「サイト上のユーザーを特定する」をクリックしたら「Webアプリケーションフロー」に戻ってきた。。無限ループこわい
想像の流れを書いてみる
必要なApp設定:
-
Request user authorization (OAuth) during installation
にチェックを入れる - Callback URL にアプリインストール後に戻ってくる自作Appの設定画面を表示するURLを設定
ページ遷移
- 自作App のウェブページにて Slack でログイン
- 自作App ウェブログイン後ページで「GitHub App をインストールする」リンクを設置する。リンク先は「ウェブアプリケーションフロー」に書いてある OAuth2 認可の URL
https://github.com/login/oauth/authorize
。URLパラメータに、インストール後に戻ってくるアプリ側のCallback URLを入れる。設定と突き合わせて確認される。 - アプリのインストールが終わったらユーザが Callback URL にアクセスしてくる。
というかんじかな。
3.のアクセス時にURLパラメータとして code
が付与されのでそれを使って github api にリクエストすることでユーザのアクセストークン等を取得でき、それで GitHub ユーザ情報を得たりすればいいっぽい?
おためし用のアプリWebページを用意
コールバックやWebhook受け取り用に以下エンドポイントも作った
ソース
さて、ガイドにあった認可用ページへのリンクを手作りして試してみる。
https://github.com/login/oauth/authorize?client_id=Iv1.9aa8ec3057a2a33a&redirect_url=https%3A%2F%2Fcoji-s-hello-github-app.vercel.app%2Fapi%2Fcallback&state=testState
お、それっぽいの出た。
「Authorize coji's Hello GitHub App」をクリックすると設定したコールバックURLに戻ってくる。
https://coji-s-hello-github-app.vercel.app/api/callback?code=*********************&state=testState
いや、そうじゃあないんですよ。インストールさせたいんすよ。
これじゃなかった感なので、ドキュメントのメニューから「GitHub Appの管理」下にある「GitHub App のインストール」を読み直す
アプリケーションのホームページのような場所にインストールURLを提供して、パブリックなアプリケーションをユーザがインストールできるようにすることができます。 そして、GitHub上のランディングページからアプリケーションのホームページを指すようにできます。
あー、これです。これ。
4. アプリのインストール URL を含むアプリのホーム ページを作成します
https://github.com/apps/<app name>/installations/new。
これkana?
以下のURLを叩いてみる
https://github.com/apps/coji-s-hello-github-app/installations/new
ああ、これですね!
リポジトリ選んでインストール押すとなんと仕込んだ callback URL に飛んだ
install_id と setup_action=install がついてるから、これを使って webhook で事前にとっといたやつと突き合わせれば良さそうだ。code もついてるから、github api でプロフィール取得とかチーム情報とかも参照できそうだね。
えー、そんなのどこにも書いてなかったやん。
しかし callback にアクセスしたあと、そのままブラウザ閉じたりしたら再設定できないんじゃない?
上記のように思ったので再度インストールリンクからいくと、やっぱり configure しか出なくてそこで save しても callback には飛ばない。そりゃそうだよね。
webhook が来た時点で紐付けないとしゃーなさそうだ。
インストールリンクには state パラメータつけたらそれを callback まで引き回してくれるみたい。これをユーザの内部IDにして webhook で飛ばしてくれたら紐付けできるんだけどな。やってみる
state=test をつけてインストールする。(先にアンインストールをやっといてから)
https://github.com/apps/coji-s-hello-github-app/installations/new?state=test
だめだ callback URL に引き渡してはくれるけど、webhook の中身には入らない。
うーん、だめだ今日はもう限界。
続きはまたこんど。
他のアプリで参考になるようなものないか探してみよ。