Skip to main content

OAuth アプリの承認

他のユーザーが OAuth app を承認できるようにすることができます。

: OAuth app の代わりに GitHub App をビルドするのを考慮します。

OAuth apps と GitHub Apps はどちらも OAuth 2.0 を使います。

GitHub Apps は、OAuth app と同様に、ユーザーに代わって動作することも、それ自体で動作することもできます。これはユーザー入力を必要としない自動化に役立ちます。 また、GitHub Apps ではきめ細かいアクセス許可が使われるため、アプリでアクセスできるリポジトリをより細かく制御でき、有効期間の短いトークンが使われます。 詳細については、「GitHub Apps と OAuth アプリの違い」および「GitHub App の作成について」を参照してください。

GitHub の OAuth の実装では、標準の認可コード許可タイプおよび Web ブラウザーを利用できないアプリケーションのために、OAuth 2.0 の Device Authorization Grant をサポートしています。

アプリケーションをテストする場合のように、標準的な方法でのアプリケーションの認可をスキップする場合は、非 Web アプリケーション フローを利用できます。

OAuth appを承認するには、ご自分のアプリに最適な承認フローを検討してください。

Web アプリケーションフロー

注: GitHub App を構築している場合は、OAuth Web アプリケーション フローを使うこともできますが、セットアップにはいくつか重要な違いがあります。 詳細については、「ユーザーに代わって GitHub アプリで認証する」を参照してください。

アプリケーションのユーザの認可のためのWebアプリケーションフローは以下のとおりです。

  1. ユーザはGitHubのアイデンティティをリクエストするためにリダイレクトされます
  2. GitHubによるサイトへのユーザのリダイレクト
  3. アプリケーションはユーザのアクセストークンと共にAPIにアクセスします

1. ユーザーの GitHub ID を要求する

GET https://github.com/login/oauth/authorize

このエンドポイントは、次の入力パラメーターを受け取ります。

Query parameter (クエリ パラメーター)Type必須説明
client_idstring必須ユーザーが登録されたときに GitHub から受け取るクライアント ID。
redirect_uristring強く推奨認可の後にユーザが送られるアプリケーション中のURL。 リダイレクト URL に関する詳細については、下を参照してください。
loginstring省略可能サインインとアプリケーションの認可に使われるアカウントを指示します。
scopestringコンテキスト依存スコープのスペース区切りリスト。 渡されなかった場合、ユーザーの scope は既定で空のリストになり、アプリケーションにはどのスコープも認可されません。 アプリケーションに対して認可したスコープがあるユーザに対しては、スコープのリストを含むOAuthの認可ページは示されません。 その代わりに、フローのこのステップはユーザがアプリケーションに認可したスコープ群で自動的に完了します。 たとえば、ユーザーが既に Web フローを 2 回実行しており、1 つのトークンで user スコープを、もう 1 つのトークンで repo スコープを認可している場合、3 番目の Web フローで scope が渡されなければ、user および repo スコープを持つトークンが返されます。
statestring強く推奨推測不能なランダムの文字列。 クロスサイトリクエストフォージェリ攻撃に対する保護として使われます。
allow_signupstring省略可能OAuthフローの間に、認証されていないユーザに対してGitHubへのサインアップの選択肢が提示されるかどうか。 既定値は、true です。 ポリシーでサインアップが禁止されている場合は、false を使用します。
promptstring省略可能select_account に設定されている場合、アカウント ピッカーを強制的に表示します。 アカウント ピッカーは、アプリケーションに HTTP 以外のリダイレクト URI がある場合、またはユーザーにサインイン済みのアカウントが複数ある場合にも表示されます。

PKCE (Proof Key for Code Exchange) パラメーターの code_challengecode_challenge_method は現時点ではサポートされていません。 CORS フライト前要求 (オプション) は現時点ではサポートされていません。

2. GitHub によってユーザーが元のサイトにリダイレクトされる

ユーザーがリクエストを受け付けると、GitHub によって一時的な code が code パラメーターに、前のステップで渡された状態が state パラメーターに入れられて、元のサイトにリダイレクトされます。 一時コードは10分後に期限切れになります。 状態が一致しない場合は、リクエストを作成したサードパーティとユーザはこのプロセスを中止しなければなりません。

この code をアクセス トークンと交換します。

POST https://github.com/login/oauth/access_token

このエンドポイントは、次の入力パラメーターを受け取ります。

パラメーター名Type必須説明
client_idstring必須OAuth app に対して GitHub から受け取ったクライアント ID。
client_secretstring必須OAuth app に対して GitHub から受け取ったクライアント シークレット。
codestring必須手順 1 に対する応答として受け取ったコード。
redirect_uristring強く推奨認可の後にユーザが送られるアプリケーション中のURL。 これを使用して、code が発行されたときに最初に指定された URI と照合して、サービスに対する攻撃を防ぐことができます。

デフォルトでは、レスポンスは以下の形式になります。

access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a&scope=repo%2Cgist&token_type=bearer

Accept ヘッダーに形式を指定した場合は、別の形式で応答を受け取ることもできます。 たとえば、Accept: application/json または Accept: application/xml です。

Accept: application/json
{
  "access_token":"gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "scope":"repo,gist",
  "token_type":"bearer"
}
Accept: application/xml
<OAuth>
  <token_type>bearer</token_type>
  <scope>repo,gist</scope>
  <access_token>gho_16C7e42F292c6912E7710c838347Ae178B4a</access_token>
</OAuth>

3. アクセス トークンを使って API にアクセスする

このアクセストークンを使えば、ユーザの代わりにAPIへのリクエストを発行できます。

Authorization: Bearer OAUTH-TOKEN
GET https://api.github.com/user

たとえば、curlでは以下のようにAuthorizationヘッダを設定できます。

curl -H "Authorization: Bearer OAUTH-TOKEN" https://api.github.com/user

アクセス トークンを受信するたびに、トークンを使用してユーザー ID を再検証する必要があります。 アプリを承認するために送信するときにユーザーはサインインしているアカウントを変更できます。サインインするたびにユーザー ID を検証しないと、ユーザー データが混在するリスクがあります。

デバイスフロー

デバイスフローを使えば、CLIツールやGit資格情報マネージャーなどのヘッドレスアプリケーションのユーザを認可できます。

デバイス フローを使用してユーザーを認可および特定するには、まずアプリケーションの設定でデバイス フローを有効にする必要があります。 アプリでデバイス フローを有効にする方法については、GitHub Apps の場合は「GitHub App 登録の変更」、OAuth apps の場合は「OAuth アプリの変更」を参照してください。

デバイスフローの概要

  1. アプリケーションはデバイスとユーザの検証コードをリクエストし、ユーザがユーザ検証コードを入力する認可URLを取得します。
  2. アプリケーションは https://github.com/login/deviceでユーザ検証コードを入力するようユーザに求めます。
  3. アプリケーションはユーザ認証のステータスをポーリングします。 ユーザがデバイスを認可すると、アプリケーションは新しいアクセストークンと共にAPIコールを発行できるようになります。

ステップ1: アプリケーションによるGitHubからのデバイス及びユーザ検証コードの要求

POST https://github.com/login/device/code

アプリケーションは、次のステップでユーザに認可を求めるために使うユーザ検証コードと検証URLをリクエストしなければなりません。 このリクエストには、アプリケーションがアクセストークンの受け取りとユーザの認可のステータスチェックに使わなければならないデバイス検証コードも返されます。

このエンドポイントは、次の入力パラメーターを受け取ります。

パラメーター名タイプ説明
client_idstring必須。 GitHub から受け取るアプリケーションのクライアント ID。
scopestringアプリがアクセスを要求しているスコープのスペース区切りのリスト。 詳しくは、「OAuth アプリのスコープ」を参照してください。

デフォルトでは、レスポンスは以下の形式になります。

device_code=3584d83530557fdd1f46af8289938c8ef79f9dc5&expires_in=900&interval=5&user_code=WDJB-MJHT&verification_uri=https%3A%2F%2Fgithub.com%2Flogin%2Fdevice
パラメーター名タイプ説明
device_codestringデバイス検証コードは40文字で、デバイスの検証に使われます。
user_codestringユーザ検証コードは、ユーザがブラウザに入力できるようにデバイスに表示されます。 このコードは8文字で、途中にハイフンがあります。
verification_uristringユーザーが user_code を入力しなければならない検証 URL: https://github.com/login/device
expires_inintegerdevice_codeuser_code の有効期限か切れるまでの秒数。 デフォルトは900秒、すなわち15分です。
intervalintegerデバイスの認可を完了するために新しいアクセス トークンのリクエスト (POST https://github.com/login/oauth/access_token) を発行する前に経過する必要がある最小秒数。 たとえばintervalが5であれば、5秒が経過するまでは新しいリクエストを発行できません。 5 秒間に複数のリクエストを発行すると、レート制限に達して slow_down エラーが返されます。

Accept ヘッダーに形式を指定した場合は、別の形式で応答を受け取ることもできます。 たとえば、Accept: application/json または Accept: application/xml です。

Accept: application/json
{
  "device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5",
  "user_code": "WDJB-MJHT",
  "verification_uri": "https://github.com/login/device",
  "expires_in": 900,
  "interval": 5
}
Accept: application/xml
<OAuth>
  <device_code>3584d83530557fdd1f46af8289938c8ef79f9dc5</device_code>
  <user_code>WDJB-MJHT</user_code>
  <verification_uri>https://github.com/login/device</verification_uri>
  <expires_in>900</expires_in>
  <interval>5</interval>
</OAuth>

ステップ2: ブラウザでユーザコードの入力をユーザに促す

デバイスはユーザ検証コードを表示し、ユーザに対してこのコードを https://github.com/login/deviceで入力するように求めます。

ステップ3: ユーザがデバイスを認証したか、アプリケーションがGitHubをポーリング

POST https://github.com/login/oauth/access_token

アプリケーションでは、デバイスおよびユーザー コードが期限切れになるか、有効なユーザー コードでアプリケーションが認可されるまで、POST https://github.com/login/oauth/access_token をポーリングするデバイス認可リクエストを発行します。 アプリケーションでは、レート制限エラーを避けるために、ステップ 1 で取得したポーリングの最小 interval を使います。 詳細については、「デバイス フローのレート制限」を参照してください。

ユーザは、15分(あるいは900秒)以内に有効なコードを入力しなければなりません。 15 分が経過すると、新たなデバイス認可コードを POST https://github.com/login/device/code でリクエストしなければなりません。

ユーザが認可されると、アプリケーションはユーザの代わりにAPIにリクエストを発行するために利用できるアクセストークンを受け取ります。

このエンドポイントは、次の入力パラメーターを受け取ります。

パラメーター名タイプ説明
client_idstring必須。 OAuth app に対して GitHub から受け取ったクライアント ID。
device_codestring必須POST https://github.com/login/device/code要求から受信したdevice_code
grant_typestring必須。 付与タイプは urn:ietf:params:oauth:grant-type:device_code でなければなりません。

デフォルトでは、レスポンスは以下の形式になります。

access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a&token_type=bearer&scope=repo%2Cgist

Accept ヘッダーに形式を指定した場合は、別の形式で応答を受け取ることもできます。 たとえば、Accept: application/json または Accept: application/xml です。

Accept: application/json
{
 "access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "token_type": "bearer",
  "scope": "repo,gist"
}
Accept: application/xml
<OAuth>
  <access_token>gho_16C7e42F292c6912E7710c838347Ae178B4a</access_token>
  <token_type>bearer</token_type>
  <scope>gist,repo</scope>
</OAuth>

デバイスフローのレート制限

ユーザがブラウザ上で検証コードをサブミットする場合、アプリケーションごとに1時間に50回のサブミットというレート制限があります。

リクエスト間で要求される最小の時間間隔 (つまり interval) 内で複数のアクセス トークン リクエスト (POST https://github.com/login/oauth/access_token) を発行すると、レート制限に達し、slow_down エラー応答が返されます。 slow_down エラー応答によって、最後の interval に 5 秒が追加されます。 詳細については、「デバイス フローのエラー コード」を参照してください。

デバイスフローのエラーコード

エラー コード説明
authorization_pendingこのエラーコードは、認可リクエストが保留中で、ユーザがユーザコードをまだ入力していない場合に生じます。 アプリケーションには、interval を超えない範囲で POST https://github.com/login/oauth/access_token リクエストをポーリングし続けることが期待されます。この際には、リクエスト間に最小の秒数を空けることが必要です。
slow_downslow_down エラーが返された場合、最小の interval、あるいは POST https://github.com/login/oauth/access_token を使用するリクエスト間に必要な時間間隔に 5 秒が追加されます。 たとえば、開始時の間隔としてリクエスト間に最小で 5 秒が必要だった場合に、slow_down エラー応答が返されると、OAuth アクセス トークンを求める新しいリクエストの発行までに最短でも 10 秒待たなければならなくなります。 エラー応答には、使用する必要がある新しい interval 情報が含まれます。
expired_tokenデバイス コードの有効期限が切れた場合は、token_expired エラーが表示されます。 デバイスコードを求める新しいリクエストを発行しなければなりません。
unsupported_grant_typeOAuth トークン リクエストの POST https://github.com/login/oauth/access_token でポーリングする際には、付与タイプを urn:ietf:params:oauth:grant-type:device_code として、入力パラメーターに含めなければなりません。
incorrect_client_credentialsデバイスフローでは、アプリケーションのクライアントIDを渡さなければなりません。これは、アプリケーションの設定ページにあります。 デバイス フローに client_secret は必要ありません。
incorrect_device_code渡されたdevice_codeが有効ではありません。
access_denied認可プロセス中にユーザーがキャンセルをクリックした場合、access_denied エラーが返され、ユーザーは検証コードを再度利用することができなくなります。
device_flow_disabledアプリケーションの設定で、デバイス フローが有効になっていません。 詳細については、「デバイス フロー」を参照してください。

詳細については、「OAuth 2.0 デバイス認証の付与」を参照してください。

非Webアプリケーションフロー

テストのような限定的な状況では、非Web認証が利用できます。 必要な場合は、personal access token の設定ページを使い、基本認証を使って personal access token を作成できます。 この手法を使えば、ユーザはいつでもアクセスを取り消せます。

リダイレクト URI

redirect_uri パラメーターは省略可能です。 省略した場合、GitHub によりユーザーは OAuth appの設定に構成されているコールバック URL にリダイレクトされます。 指定する場合、リダイレクト URL のホスト (サブドメインを除く) とポートは、コールバック URL と完全に一致している必要があります。 リダイレクト URL のパスは、コールバック URL のサブディレクトリを参照していなければなりません。

CALLBACK: http://example.com/path

GOOD: http://example.com/path
GOOD: http://example.com/path/subdir/other
GOOD: http://oauth.example.com/path
GOOD: http://oauth.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

ループバック リダイレクト URI

オプションredirect_uriパラメーターは、デスクトップ コンピューターで実行されているネイティブ アプリケーションに便利なLoopback URL にも使用できます。 アプリケーションでループバック URL とポートを指定した場合、アプリケーションを認可した後、ユーザーは指定した URL とポートにリダイレクトされます。 redirect_uri は、アプリのコールバック URL で指定されたポートと一致している必要はありません。

http://127.0.0.1/pathコールバック URL については、アプリケーションがポート1234でリッスンしている場合にこのredirect_uriを使用できます。

http://127.0.0.1:1234/path

OAuth の RFC では、localhost の使用は推奨されておらず、代わりにループバック リテラル 127.0.0.1 または IPv6 ::1 を使うことが推奨されています。

OAuth apps の複数のトークンを作成する

ユーザ/アプリケーション/スコープの組み合わせに対して複数のトークンを作成し、特定のユースケースに対応できます。

これは、お使いの OAuth appが、サインインに GitHub を利用し、基本的なユーザー情報しか必要としない 1 つのワークフローをサポートしている場合に便利です。 別のワークフローはユーザのプライベートリポジトリへのアクセスを必要としていてもかまいません。 複数のトークンを使うと、OAuth appはそれぞれのユースケースに対して Web フローを実行でき、必要なスコープだけをリクエストします。 ユーザーがサインインにアプリケーションだけを使う場合は、OAuth appにプライベート リポジトリへのアクセスを付与する必要はありません。

ユーザー/アプリケーション/スコープの組み合わせごとに、1 時間あたり作成されるトークン数には 10 という上限があります。 アプリケーションで同じユーザーと同じスコープに対して 10 個を超えるトークンが作成された場合、同じユーザー/アプリケーション/スコープの組み合わせを持つ最も古いトークンが取り消されます。 ただし、時間単位のレート制限に達しても、最も古いトークンは取り消されません。 代わりに、ブラウザー内で再承認プロンプトがトリガーされ、ユーザーはアプリに付与しているアクセス許可を再確認するよう求められます。 このプロンプトは、アプリが 1 時間以内にユーザーに 10 個のトークンを要求する理由がほとんどないため、アプリが陥っている可能性のある無限ループを中断させることを目的としています。

警告: OAuth app からすべてのアクセス許可を取り消すと、ユーザーの代わりにアプリケーションで生成されたすべての SSH キー (デプロイ キーを含む) が削除されます。

ユーザにアクセスをレビューしてもらう

OAuth appへの承認情報へリンクし、ユーザーがアプリケーションの承認を確認したり、取り消したりすることができます。

このリンクを構築するには、アプリケーションを登録したときに GitHub から受け取った OAuth appの client_id が必要になります。

https://github.com/settings/connections/applications/:client_id

ヒント: OAuth appでアクセスできるユーザーのリソースについて詳しくは、「ユーザのリソースを調べる」をご覧ください。

トラブルシューティング

参考資料