GithubのOAuth2.0の仕様について理解する(Githubログイン)
あの楽ちんなGithubログインボタン
結構前からですが、他のSNSサービスや比較的数多くのアカウント登録数を持っているサービスが採用しているOAuth2.0ですけど、自分が関わっているプロダクトで使う必要が出てきたので、仕様と使い方にGithubの公式ドキュメントを読みながらまとめてみた。
OAuth | GitHub Developer Guide
公式ドキュメントの大体合ってる日本語訳
※実際の翻訳と異なることが多少あります。大体そんな感じという日本語訳です。
OAuth2は外部アプリケーションがユーザーのGithubアカウントが持っているプライベートな情報にパスワードなしで情報にアクセスすることが出来るプロトコルです。トークンは特定のタイプのデータに限定でき、ユーザーはそのトークンをいつでも消せるということらしい。このトークン仕組みははBasic認証よりも良いですよ?みらいなことが書いてある。
つまり、トークンとやらを発行して、そのトークンを使うことで許可された範囲で操作出来るよってことらしい。Basic認証よりイケてるからみんな使ってこうぜ!的なことが言いたいのだと思う。
全ての開発者は、これを利用する前にアプリケーションの登録をする必要があります。登録されたOAuthアプリケーションのには、固有のClient IDとClient Secretが割り当てられます。
※このClient Secretは絶対に共有しないでください!
開発者の自身で使用するための個人アクセストークンを作成したり、以下に紹介するフローを実装することで、他のユーザーがアプリケーションを許可することが出来ます。
ここで出たClient Secretは間違って、Githubとかに上げると悪用されるので、公開しないようにしてくださいという意味だと思われる。
GithubのOAuth実装は、authorization code grant typeをサポートしています。開発者は以下で説明するWebアプリケーションフローを実装して、認証コードを取得し、それをトークンに交換する必要があります。(implicit grant typeはサポートしていません)
Webアプリケーションでのフロー
大体こんな感じだと思う。
1.ユーザーはリダイレクトでGithubへアクセスする
GET https://github.com/login/oauth/authorize
設定できるパラメーター
*は必須という意味です。
Name | Type | 説明 |
---|---|---|
client_id * | string | 登録時にい発行されたクライアントID |
redirect_uri | string | 承認後にユーザーのリダイレクト先。(アプリケーションURL) |
scope | string | scopeスペースで区切られたスコープのリスト。scopeは空の場合は、アプリケーションのscopeを許可していないユーザーの空リストにデフォルトで設定されます。アプリケーションのscopeを承認したユーザーの場合は、scopeのリストを含むOAuth認証ページは表示されません。その代わり、このフローでは、ユーザーのアプリケーションに対しての承認を自動的に処理する。 |
state | string | サイト間のやり取りをする際のCSRF対策に使うランダムな文字列。これが漏れると攻撃されるので、取扱には気をつけたい。 |
allow_signup | string | 認証されていないユーザーに、OAuthフロー中にGithubにサインアップするオプションを提供するかどうかを設定する。つまり、認証フローに入る前からGithubにログイン済みのユーザーしか許可しないかどうかを決定するようです。もし、許可する場合はデフォルトで設定されているtrue で、許可したくない場合はfalse とするようです。 |
補足
redirect_uri
リダイレクトのURLには以下のようなルールがあります。
OAuth | GitHub Developer Guide
CALLBACK: http://example.com/path GOOD: http://example.com/path GOOD: http://example.com/path/subdir/other BAD: http://example.com/bar BAD: http://example.com/ BAD: http://example.com:8080/path BAD: http://oauth.example.com:8080/path BAD: http://example.org
示されている例が少し分かりにくかったので、ありそうな例を書きました。
http://localhost/login ◯http://localhost/login/callback ×http://localhost/callback
scope
OAuth | GitHub Developer Guide
このscopeというのは、アプリケーションから取得または操作を許可する範囲のことを指している。
例えば、何も設定をしないno scope
の場合は、公開されている情報に読み取り専用でアクセスを許可されたり、user:email
などにすると、ユーザーがGithubに登録しているメールアドレスへアクセスが出来るなど。様々なレベルのscopeがあるので、必要に応じて設定すると良いらしい。
2.Githubからアプリケーションにリダイレクトする
POST https://github.com/login/oauth/access_token
ユーザーがリクエストを受け入れると、Githubはcode
パラメーターの一時コードと1の手順で指定したstate
をパラメーターに指定したアプリケーションにリダイレクトされます。この時にstateが違った場合は攻撃の可能生が高いため、OAuthのフローを中止するべきです。
設定できるパラメーター
*は必須という意味です。
Name | Type | 説明 |
---|---|---|
client_id* | string | アプリケーション登録時に発行されたclient_id |
client_secret* | string | アプリケーション登録時に発行されたclient_secret |
code* | string | 1の手順の応答で受け取る。tokenとの引き換え券のようなもの。 |
redirect_uri | string | 承認後にユーザーがリダイレクトされるアプリケーションのURL。リダイレクトのルールは先程紹介したものと同じです。 |
POST https://github.com/login/oauth/access_token
へのレスポンス
access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&scope=user%2Cgist&token_type=bearer
Accept ヘッダーに応じて、様々な形式で受け取ることが出来ます。
Accept: application/json {"access_token":"e72e16c7e42f292c6912e7710c838347ae178b4a", "scope":"repo,gist", "token_type":"bearer"} Accept: application/xml <OAuth> <token_type>bearer</token_type> <scope>repo,gist</scope> <access_token>e72e16c7e42f292c6912e7710c838347ae178b4a</access_token> </OAuth>
3. tokenを使ってAPIへリクエストする
ここまでのフローで受け取ったaccess_tokenでAPIへリクエストが出来ます。
tokenは以下のようなパラメーターで渡すパターン。
GET https://api.github.com/user?access_token=...
HeaderのAuthorizationを使って渡すことも出来ます。
Authorization: token OAUTH-TOKEN
curlコマンドでは以下のようになります。
curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com/user
なんとなく分かった気がする。