GitHub Enterprise Server の OAuth の実装では、標準の認可コード許可タイプおよび Web ブラウザーを利用できないアプリケーションのために、OAuth 2.0 の Device Authorization Grant をサポートしています。
アプリケーションをテストする� �合のように、標準的な方法でのアプリケーションの認可をスキップする� �合は、非 Web アプリケーション フローを利用できます。
OAuthアプリケーションを認可する� �合は、そのアプリケーションにどの認可フローが最も適切かを考慮してく� さい。
- Web アプリケーション フロー: ブラウザーで実行される標準的な OAuth App のユーザーを認可するために使われます。 (暗黙的な許可の種類はサポートされていません。)
- デバイスフロー: CLI ツールなど、ヘッドレス アプリケーションに使われます。
Web アプリケーションフロー
注: GitHub App を構築している� �合は、OAuth Web アプリケーション フローを使うこともできますが、セットアップにはいくつか重要な違いがあります。 詳細については、「GitHub App のユーザーの特定と認可」を参照してく� さい。
アプリケーションのユーザの認可のためのWebアプリケーションフローは以下のとおりです。
- ユーザはGitHubのアイデンティティをリクエストするためにリダイレクトされます
- GitHubによるサイトへのユーザのリダイレクト
- アプリケーションはユーザのアクセストークンと共にAPIにアクセスします
1. ユーザーの GitHub ID を要求する
GET http(s)://HOSTNAME/login/oauth/authorize
GitHub アプリで login
パラメーターを指定すると、ユーザーは、使用できるアカウントでサインインしてアプリを認可するように求められます。
パラメーター
名前 | 型 | 説明 |
---|---|---|
client_id | string | [必� �] 。 ユーザーが登録されたときに GitHub から受け取るクライアント ID。 |
redirect_uri | string | 認可の後にユーザが送られるアプリケーション中のURL。 リダイレクト URL に関する詳細については、下を参照してく� さい。 |
login | string | サインインとアプリケーションの認可に使われるアカウントを指示します。 |
scope | string | スコープのスペース区切りリスト。 渡されなかった� �合、ユーザーの scope は既定で空のリストになり、アプリケーションにはどのスコープも認可されません。 アプリケーションに対して認可したスコープがあるユーザに対しては、スコープのリストを含むOAuthの認可ページは示されません。 その代わりに、フローのこのステップはユーザがアプリケーションに認可したスコープ群で自動的に完了します。 たとえば、ユーザーが既に Web フローを 2 回実行しており、1 つのトークンで user スコープを、もう 1 つのトークンで repo スコープを認可している� �合、3 番目の Web フローで scope が渡されなければ、user および repo スコープを持つトークンが返されます。 |
state | string | 推測不能なランダ� の文字列。 クロスサイトリクエストフォージェリ攻撃に対する保護として使われます。 |
allow_signup | string | OAuthフローの間に、認証されていないユーザに対してGitHubへのサインアップの選択肢が提示されるかどうか。 既定値は、true です。 ポリシーでサインアップが禁止されている� �合は、false を使用します。 |
2. GitHub によってユーザーが元のサイトにリダイレクトされる
ユーザーがリクエストを受け付けると、GitHub Enterprise Server によって一時的な code
が code パラメーターに、前のステップで渡された状態が state
パラメーターに入れられて、元のサイトにリダイレクトされます。 一時コードは10分後に期限切れになります。 状態が一致しない� �合は、リクエストを作成したサードパーティとユーザはこのプロセスを中止しなければなりません。
この code
をアクセス トークンと交換します。
POST http(s)://HOSTNAME/login/oauth/access_token
パラメーター
名前 | 型 | 説明 |
---|---|---|
client_id | string | 必� �。 OAuth App に対して GitHub Enterprise Server から受け取ったクライアント ID。 |
client_secret | string | 必� �。 OAuth App に対して GitHub Enterprise Server から受け取ったクライアント シークレット。 |
code | string | 必� �。 手� � 1 に対する応答として受け取ったコード。 |
redirect_uri | string | 認可の後にユーザが送られるアプリケーション中のURL。 |
[応答]
デフォルトでは、レスポンスは以下の形式になります。
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 http(s)://HOSTNAME/api/v3/user
たとえば、curlでは以下のようにAuthorizationヘッダを設定できます。
curl -H "Authorization: Bearer OAUTH-TOKEN" http(s)://HOSTNAME/api/v3/user
デバイスフロー
注: デバイス フローはパブリック ベータ版であり、変更される可能性があります。
デバイスフローを使えば、CLIツールやGit認証情� �マネージャーなどのヘッドレスアプリケーションのユーザを認可できます。
デバイスフローの概要
- アプリケーションはデバイスとユーザの検証コードをリクエストし、ユーザがユーザ検証コードを入力する認可URLを取得します。
- アプリケーションは
http(s)://HOSTNAME/login/device
でユーザ検証コードを入力するようユーザに求めます。 - アプリケーションはユーザ認証のステータスをポーリングします。 ユーザがデバイスを認可すると、アプリケーションは新しいアクセストークンと共にAPIコールを発行できるようになります。
ステップ1: アプリケーションによるGitHubからのデバイス及びユーザ検証コードの要求
POST http(s)://HOSTNAME/login/device/code
アプリケーションは、次のステップでユーザに認可を求めるために使うユーザ検証コードと検証URLをリクエストしなければなりません。 このリクエストには、アプリケーションがアクセストークンの受け取りとユーザの認可のステータスチェックに使わなければならないデバイス検証コードも返されます。
入力パラメーター
名前 | 型 | 説明 |
---|---|---|
client_id | string | 必� �。 GitHub Enterprise Server から受け取るアプリケーションのクライアント ID。 |
scope | string | アプリケーションがアクセスをリクエストしているスコープ。 |
[応答]
デフォルトでは、レスポンスは以下の形式になります。
device_code=3584d83530557fdd1f46af8289938c8ef79f9dc5&expires_in=900&interval=5&user_code=WDJB-MJHT&verification_uri=https%3A%2F%HOSTNAME%2Flogin%2Fdevice
Accept
ヘッダーに形式を指定した� �合は、別の形式で応答を受け取ることもできます。 たとえば、Accept: application/json
または Accept: application/xml
です。
Accept: application/json
{
"device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5",
"user_code": "WDJB-MJHT",
"verification_uri": "http(s)://HOSTNAME/login/device",
"expires_in": 900,
"interval": 5
}
Accept: application/xml
<OAuth>
<device_code>3584d83530557fdd1f46af8289938c8ef79f9dc5</device_code>
<user_code>WDJB-MJHT</user_code>
<verification_uri>http(s)://HOSTNAME/login/device</verification_uri>
<expires_in>900</expires_in>
<interval>5</interval>
</OAuth>
応答パラメーター
名前 | 型 | 説明 |
---|---|---|
device_code | string | デバイス検証コードは40文字で、デバイスの検証に使われます。 |
user_code | string | ユーザ検証コードは、ユーザがブラウザに入力できるようにデバイスに表示されます。 このコードは8文字で、途中にハイフンがあります。 |
verification_uri | string | ユーザーが user_code を入力しなければならない検証 URL: http(s)://HOSTNAME/login/device 。 |
expires_in | integer | device_code と user_code の有効期限か切れるまでの秒数。 デフォルトは900秒、すなわち15分です。 |
interval | integer | デバイスの認可を完了するために新しいアクセス トークンのリクエスト (POST http(s)://HOSTNAME/login/oauth/access_token ) を発行する前に経過する必要がある最小秒数。 たとえばintervalが5であれば、5秒が経過するまでは新しいリクエストを発行できません。 5 秒間に複数のリクエストを発行すると、レート制限に達して slow_down エラーが返されます。 |
ステップ2: ブラウザでユーザコードの入力をユーザに促す
デバイスはユーザ検証コードを表示し、ユーザに対してこのコードを http(s)://HOSTNAME/login/device
で入力するように求めます。
ステップ3: ユーザがデバイスを認証したか、アプリケーションがGitHubをポーリング
POST http(s)://HOSTNAME/login/oauth/access_token
アプリケーションでは、デバイスおよびユーザー コードが期限切れになるか、有効なユーザー コードでアプリケーションが認可されるまで、POST http(s)://HOSTNAME/login/oauth/access_token
をポーリングするデバイス認可リクエストを発行します。 アプリケーションでは、レート制限エラーを避けるために、ステップ 1 で取得したポーリングの最小 interval
を使います。 詳細については、「デバイス フローのレート制限」を参照してく� さい。
ユーザは、15分(あるいは900秒)以内に有効なコードを入力しなければなりません。 15 分が経過すると、新たなデバイス認可コードを POST http(s)://HOSTNAME/login/device/code
でリクエストしなければなりません。
ユーザが認可されると、アプリケーションはユーザの代わりにAPIにリクエストを発行するために利用できるアクセストークンを受け取ります。
入力パラメーター
名前 | 型 | 説明 |
---|---|---|
client_id | string | 必� �。 OAuth App に対して GitHub Enterprise Server から受け取ったクライアント ID。 |
device_code | string | 必� �。 POST http(s)://HOSTNAME/login/device/code リクエストから受け取ったデバイス検証コード。 |
grant_type | string | 必� �。 付与タイプは 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 http(s)://HOSTNAME/login/oauth/access_token
) を発行すると、レート制限に達し、slow_down
エラー応答が返されます。 slow_down
エラー応答によって、最後の interval
に 5 秒が追� されます。 詳細については、「デバイス フローのエラー」を参照してく� さい。
デバイスフローのエラーコード
エラー コード | 説明 |
---|---|
authorization_pending | このエラーコードは、認可リクエストが保留中で、ユーザがユーザコードをま� 入力していない� �合に生じます。 アプリケーションには、interval を超えない範囲で POST http(s)://HOSTNAME/login/oauth/access_token リクエストをポーリングし続けることが期待されます。この際には、リクエスト間に最小の秒数を空けることが必要です。 |
slow_down | slow_down エラーが返された� �合、最小の interval 、あるいは POST http(s)://HOSTNAME/login/oauth/access_token を使用するリクエスト間に必要な時間間隔に 5 秒が追� されます。 たとえば、開始時の間隔としてリクエスト間に最小で 5 秒が必要� った� �合に、slow_down エラー応答が返されると、OAuth アクセス トークンを求める新しいリクエストの発行までに最短でも 10 秒待たなければならなくなります。 エラー応答には、使用する必要がある新しい interval 情� �が含まれます。 |
expired_token | デバイス コードの有効期限が切れた� �合は、token_expired エラーが表示されます。 デバイスコードを求める新しいリクエストを発行しなければなりません。 |
unsupported_grant_type | OAuth トークン リクエストの POST http(s)://HOSTNAME/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 エラーが返され、ユーザーは検証コードを再び利用することができなくなります。 |
詳細については、「OAuth 2.0 デバイス認証の付与」を参照してく� さい。
非Webアプリケーションフロー
テストのような限定的な状況では、非Web認証が利用できます。 必要な� �合は、personal access token の設定ページを使い、基本認証を使って personal access token を作成できます。 この手法を使えば、ユーザはいつでもアクセスを取り消せます。
注: 非 Web アプリケーション フローを使って OAuth2 トークンを作成する� �合で、ユーザーが 2 要� 認証を有効化しているなら、2 要� 認証の利用方法を必ず理解しておいてく� さい。
リダイレクト URI
redirect_uri
パラメーターは省略可能です。 指定しなかった� �合、GitHub では OAuth アプリケーションで設定されているコールバック 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
パラメーターは、ループバック URL にも使用できます。 アプリケーションでループバック URL とポートを指定した� �合、アプリケーションを認可した後、ユーザーは指定した URL とポートにリダイレクトされます。 redirect_uri
は、アプリのコールバック URL で指定されたポートと一致している必要はありません。
http://127.0.0.1/path
コールバック URL には、次の redirect_uri
を使用できます。
http://127.0.0.1:1234/path
OAuth の RFC では、localhost
の使用は推奨されておらず、代わりにループバック リテラル 127.0.0.1
または IPv6 ::1
を使うことが推奨されています。
OAuthアプリケーションに複数のトークンを作成する
ユーザ/アプリケーション/スコープの組み合わせに対して複数のトークンを作成し、特定のユースケースに対応できます。
OAuthアプリケーションが、サインインにGitHubを利用し、基本的なユーザ情� �しか必要としないワークフローを1つサポートする� けであれば、これは有益です。 別のワークフローはユーザのプライベートリポジトリへのアクセスを必要としていてもかまいません。 複数のトークンを使えば、OAuthアプリケーションはそれぞれのユースケースに対してWebフローを実行でき、必要なスコープ� けをリクエストします。 ユーザがサインインにアプリケーション� けを使うなら、ユーザは自分のプライベートリポジトリへのアクセスをOAuthアプリケーションに許可する必要はありません。
ユーザ/アプリケーション/スコープの組み合わせごとに、発行できるトークン数には10という上限があります。 アプリケーションで同じユーザーと同じスコープに対して 10 個を超えるトークンが作成された� �合、同じユーザー/アプリケーション/スコープの組み合わせを持つ最も古いトークンが取り消されます。
警告: OAuth App からすべてのアクセス許可を取り消すと、ユーザーの代わりにアプリケーションで生成されたすべての SSH キー (デプロイ キーを含む) が削除されます。
ユーザにアクセスをレビューしてもらう
OAuthアプリケーションへの認可情� �へリンクし、ユーザがアプリケーションの認可をレビューし、取り消しできるようにすることができます。
このリンクを構築するには、アプリケーションを登録したときに GitHub から受け取った OAuth App の client_id
が必要です。
http(s)://HOSTNAME/settings/connections/applications/:client_id
ヒント: OAuth App でアクセスできるユーザーのリソースについてさらに学ぶには、「ユーザーのリソースを調べる」を参照してく� さい。