はじめに
最近 GitHub API を使う機会があり、認証方法が3種類あって少し迷ったので、自分なりに理解した内容を整理してみました。
GitHub公式のドキュメントは以下です。
GitHub API の認証方法3種
オープンなリポジトリの操作など、認証をしなくても GitHub API を使える場合がありますが、大抵の場合は認証が必要になります。GitHub API を使用する際の認証方法は現在以下の3種類あります。(他にもあったら教えてください!)
- Personal Access Token(PAT)による認証
- OAuth app による認証
- GitHub App による認証
それぞれ簡単に説明していきます。
Personal Access Token(PAT)による認証
Personal Access Tokenとは、その名の通り個人用のアクセストークンです。
GitHub の設定ページまたは以下リンクからトークン管理ページに飛べます。
https://github.com/settings/tokens
作成時に、名前と有効期限の設定、そしてトークンでアクセス可能な情報の種類を選択できます。
有効期限を無制限にすることも可能ですが、トークンが誤って流出した場合などで危険なので設定しておいた方がいいです。一方、有効期限を設定する場合は、有効期限が切れるたびに再生成が必要なので、忘れないようにする必要があります。
例えば企業が運営するWebサービスにこのトークンを使用する場合は、トークンの有効期限切れでサービスが止まってしまわないようにすることが必要です。またユーザーに紐付くので、トークン生成したメンバーが退職した場合なども考慮する必要があります。
このように、Personal Access Tokenは個人として使う分には問題ないですが、企業として使用する場合は注意が必要で、場合によっては後述の OAuth 認証や GitHub App を使った認証の方が適している場合があります。
生成したトークンを使う方法は簡単です。以下のようにヘッダーにトークンを指定して、APIのエンドポイントにリクエストを送るだけです。
$ curl -H "Authorization: token ここにトークンを入れる" https://api.github.com/user
以上をまとめると、Personal Access Token(PAT)を使った認証は以下のような認証方法となります。
- 設定ページで作成した、個人に紐付くトークン を使用する
- トークンを ヘッダー に指定することで API へアクセスできる
- 自分の GitHubアカウントで閲覧可能な情報にアクセスできる
- 有効期限を設定が可能で、有効期限切れに注意
OAuth app による認証
現在、OAuth app による認証よりも、後述の GitHub App による認証の方が推奨されているようです。
OAuth は、例えば自分が作ったWebアプリケーションでユーザーが GitHub アカウントでログインできる機能を作る際に役立つ認証方法です。Qiita も GitHub アカウントでログインできるようになっていますが、これも OAuth が使用されています。
より正確には、OAuth は「ユーザーのGitHubアカウントの権限の一部」をWebサービスにも与えて、Webサービス側が「そのユーザーのGitHubの情報にアクセスする」ための仕組みです。
GitHub の設定ページまたは以下リンクから、OAuth app の作成ができます。
https://github.com/settings/developers
アプリケーション名やホームページURL、コールバックURLなどを設定して作成すると、 client_id
や client_secret
が生成されます。
OAuth やコールバックURLについて知らない場合、以下の記事がOAuthについて丁寧に説明されているので、おすすめです。
GitHub の OAuth app による認可の流れを簡単に説明すると、以下のようになります。
- 以下のようにURLを設定したリンクをWebアプリケーション上に用意する
https://github.com/login/oauth/authorize?scope=(スコープ)&client_id=(client_id)
- ユーザーがこのリンクから GitHub のページにアクセスし、連携を許可する
- コールバックURLにリダイレクトされてサーバーにコードが渡される
- 以下URLに渡されたコードや
client_id
client_secret
をパラメータとして渡し、トークンを取得するhttps://github.com/login/oauth/access_token
スコープの設定方法など、詳細は以下の公式ドキュメントに記載されているので、そちらも確認の上実装しましょう。
トークンは PAT の時と同様に、ヘッダーに指定してAPIにリクエストを送ります。
$ curl -H "Authorization: Bearer OAUTH-TOKEN" https://api.github.com/user
以上をまとめると、OAuth app による認証は以下のような認証方法となります。
- OAuth の認可フロー で取得したトークンを使用する
- トークンを ヘッダー に指定することで API へアクセスできる
- 連携したユーザー の指定したスコープの情報にアクセスできる
- 現在は GitHub App による認証の方が推奨されている
GitHub App
GitHub App はできることが多いので、一言で説明することは難しいですが、GitHub API へのアクセスだけでなく、GitHub で発生するイベントに基づいて何か実行することも可能です。
ここでは自分で作った GitHub App を自分の GitHub アカウントにインストールし、APIにアクセスするためのトークンを取得する方法のみ説明します。
初めに以下から GitHub App を作成します。
https://github.com/settings/apps
設定できる項目が多いですが、GitHub App の名前とホームページのURLを設定すればOKです。
作成後、以下の操作を行い必要な値を控えておきます。
-
Generate a private key
から、秘密鍵を生成する - サイドバーの Public pageのリンクから、GitHub App をインストールする
- インストール後、
https://github.com/settings/installations/XXXXXXXXXXXX
のようなページに飛ぶので、XXXXXXXXXXXX
の部分をコピーしておく (後でINSTALLATION_ID
として使います。)
- インストール後、
これで必要な値がそろったので、次は認証に使うトークンの取得を行います。
取得の方法は以下の公式ドキュメントに記載されています。
トークンは以下のようにリクエストすることで、取得できます。
curl --request POST \
--url "https://api.github.com/app/installations/INSTALLATION_ID/access_tokens" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer JWT" \
--header "X-GitHub-Api-Version: 2022-11-28"
INSTALLATION_ID
は先ほど用意した値を使用します。JWT は以下に記載の方法で秘密鍵をもとに生成したJSON Web トークンを使います。
そうして取得したトークンを、PAT や OAuth app と同様に、以下のようにヘッダーに指定してAPIにリクエストします。
$ curl -H "Authorization: Bearer OAUTH-TOKEN" https://api.github.com/user
このように、GitHub App の認証は複雑なので、Octokit を使用してトークンを取得する方法がオススメです。
Octokit は GitHub API 用のライブラリで、JavaScript, C#, Rubyなどの言語に対応しています。JWTを以下のように渡すだけで、トークンの取得ができます。
client = Octokit::Client.new(bearer_token: jwt_token)
access_token = client.create_app_installation_access_token(INSTALLATION_ID).token
以上をまとめると、GitHub App による認証は以下のような認証方法となります。
- GitHubの個人アカウントだけでなく、Organization でも GitHub App を作成できる
- GitHub App をユーザーまたは Organization に インストールする必要がある
- JWTの生成 など、トークンを取得する方法が少し複雑
- スコープや有効期間などの理由から、OAuth apps よりも推奨されている
おわりに
認証・認可は複雑で、理解するまで少し時間がかかりますが、学べることは多いので、APIを使う際にぜひ自分なりに理解した内容を記事にまとめてみることがおすすめです。
僕もこの記事を書くことで、自分の中で曖昧だった部分の理解が深まりました。GitHub App の使い方についてはまだAPIを使う場合しかちゃんと理解できていませんが、他にも便利な使い方がありそうなので、また別の記事としてまとめようと思います。