CLIアプリケーション向けGitHub OAuth 2.0
デバイスコードフローを使用したコマンドラインツールでのGitHub OAuth 2.0認証の実装。完全なフローウォークスルー付き。
Real-World Flows
詳細な説明
CLI向けGitHub OAuth 2.0
GitHubはデバイスコードフローをサポートしており、ユーザーが直接資格情報を入力できないCLIアプリケーションに最適です。CLIがコードとURLを表示し、ユーザーがブラウザで認証すると、CLIがトークンを受信します。
GitHub OAuthエンドポイント
| エンドポイント | URL |
|---|---|
| デバイス認可 | https://github.com/login/device/code |
| トークン | https://github.com/login/oauth/access_token |
| ユーザーAPI | https://api.github.com/user |
ステップ1:GitHub OAuthアプリを作成
- GitHubの設定 > 開発者設定 > OAuthアプリに移動
- 新しいアプリケーションを登録
- 注意:GitHub OAuthアプリはデバイスフローにclient_secretの要件がない
client_idを保存
ステップ2:デバイスコードをリクエスト
curl -X POST https://github.com/login/device/code \
-H "Accept: application/json" \
-d "client_id=YOUR_CLIENT_ID&scope=repo%20user"
レスポンス:
{
"device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5",
"user_code": "WDJB-MJHT",
"verification_uri": "https://github.com/login/device",
"expires_in": 899,
"interval": 5
}
ステップ3:ユーザーに表示
! まずワンタイムコードをコピー: WDJB-MJHT
- Enterキーを押してブラウザでgithub.comを開きます...
ステップ4:トークンをポーリング
curl -X POST https://github.com/login/oauth/access_token \
-H "Accept: application/json" \
-d "client_id=YOUR_CLIENT_ID\
&device_code=3584d83530557fdd1f46af8289938c8ef79f9dc5\
&grant_type=urn:ietf:params:oauth:grant-type:device_code"
保留中のレスポンス:{"error": "authorization_pending"}
成功レスポンス:
{
"access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a",
"token_type": "bearer",
"scope": "repo,user"
}
ステップ5:トークンを使用
curl -H "Authorization: Bearer gho_16C7e42F292c6912E7710c838347Ae178B4a" \
https://api.github.com/user
Node.js実装
const open = require("open");
async function githubDeviceAuth(clientId) {
// ステップ1: デバイスコードを取得
const codeRes = await fetch("https://github.com/login/device/code", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
body: `client_id=${clientId}&scope=repo user`,
}).then(r => r.json());
console.log(`コードを入力: ${codeRes.user_code}`);
await open(codeRes.verification_uri);
// ステップ2: トークンをポーリング
while (true) {
await new Promise(r => setTimeout(r, codeRes.interval * 1000));
const tokenRes = await fetch(
"https://github.com/login/oauth/access_token",
{
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
body: `client_id=${clientId}&device_code=${codeRes.device_code}&grant_type=urn:ietf:params:oauth:grant-type:device_code`,
}
).then(r => r.json());
if (tokenRes.access_token) return tokenRes.access_token;
if (tokenRes.error === "authorization_pending") continue;
throw new Error(tokenRes.error_description || tokenRes.error);
}
}
一般的なGitHubスコープ
| スコープ | アクセス |
|---|---|
repo |
プライベートリポジトリの完全な制御 |
repo:status |
コミットステータスの読み書き |
user |
ユーザープロフィールデータの読み取り |
read:org |
組織メンバーシップの読み取り |
gist |
Gistの作成 |
workflow |
GitHub Actionsワークフローの更新 |
ユースケース
GitHubで認証する必要があるCLIツール(GitHub CLI、Terraform、カスタムデプロイツールなど)の構築。デバイスコードフローにより、ターミナルにトークンを貼り付けることなくブラウザで安全に認証できます。