Skip to main content

将 GitHub OAuth 与 Copilot SDK 配合使用

让用户使用其 GitHub 帐户进行身份验证,以便通过应用程序使用 GitHub Copilot 。

谁可以使用此功能?

GitHub Copilot SDK 适用于所有 Copilot 计划。

注意

          Copilot SDK 当前处于 技术预览版. 功能和可用性可能会发生更改。

在您的应用程序中直接提供GitHub帐户身份验证,以连接用户到GitHub Copilot。

          **最适合:** 多用户应用、具有组织访问控制的内部工具、SaaS 产品和用户已有 GitHub 帐户的应用。

工作原理

          GitHub创建 OAuth 应用(或GitHub App),用户对其进行授权,并将其访问令牌传递给 SDK。               Copilot 使用其 Copilot 订阅代表每个经过身份验证的用户发出请求。 有关此流和体系结构的详细序列图,请参阅 `github/copilot-sdk`[存储库](https://github.com/github/copilot-sdk/blob/main/docs/setup/github-oauth.md#how-it-works)。

          **主要特征:**
  • 每个用户使用自己的 GitHub 帐户进行身份验证。
  •         Copilot 使用情况按每个用户的订阅计费。
    
  • 支持 GitHub 组织和企业帐户。
  • 你的应用永远不会处理模型 API 密钥-GitHub 管理所有内容。

步骤 1:创建 GitHub OAuth 应用

  1. 转到“设置”>“开发人员设置”>“OAuth 应用”>“新的 OAuth 应用”。 对于组织,请转到 组织设置>开发人员设置
  2. 填写以下字段: * 应用程序名称:应用的名称。 * 主页 URL:应用的 URL。 * 授权回调 URL:您的 OAuth 回调终结点(例如 https://YOUR-APP.com/auth/callback)。 将 YOUR-APP.com 替换为你的域。
  3. 记下 客户端 ID 并生成 客户端密码

注意

          GitHub Apps 和 OAuth 应用都可以与 SDK 一起使用。 
          GitHub Apps 提供更细致的权限控制,建议用于新项目。 OAuth 应用设置更简单。 从 SDK 的角度来看,令牌流是相同的。

步骤 2:实现 OAuth 流

应用程序处理标准 GitHub OAuth 流。 下面显示了服务器端令牌交换:

// Server-side: exchange authorization code for user token
async function handleOAuthCallback(code: string): Promise<string> {
    const response = await fetch("https://github.com/login/oauth/access_token", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            Accept: "application/json",
        },
        body: JSON.stringify({
            client_id: process.env.GITHUB_CLIENT_ID,
            client_secret: process.env.GITHUB_CLIENT_SECRET,
            code,
        }),
    });

    const data = await response.json();
    return data.access_token; // gho_xxxx or ghu_xxxx
}

步骤 3:将令牌传递给 SDK

为每个经过身份验证的用户创建 SDK 客户端,并传递其令牌。

Node.js/TypeScript

import { CopilotClient } from "@github/copilot-sdk";

// Create a client for an authenticated user
function createClientForUser(userToken: string): CopilotClient {
    return new CopilotClient({
        githubToken: userToken,
        useLoggedInUser: false,  // Don't fall back to CLI sign-in
    });
}

// Usage
const client = createClientForUser("USER-ACCESS-TOKEN");
const session = await client.createSession({
    sessionId: `user-${userId}-session`,
    model: "gpt-4.1",
});

const response = await session.sendAndWait({ prompt: "Hello!" });

USER-ACCESS-TOKEN 替换为用户的 OAuth 访问令牌(例如 gho_xxxx)。

Python

from copilot import CopilotClient, PermissionHandler

def create_client_for_user(user_token: str) -> CopilotClient:
    return CopilotClient({
        "github_token": user_token,
        "use_logged_in_user": False,
    })

# Usage
client = create_client_for_user("USER-ACCESS-TOKEN")
await client.start()

session = await client.create_session(
    on_permission_request=PermissionHandler.approve_all,
    model="gpt-4.1",
    session_id=f"user-{user_id}-session",
)

response = await session.send_and_wait({"prompt": "Hello!"})

Go

func createClientForUser(userToken string) *copilot.Client {
    return copilot.NewClient(&copilot.ClientOptions{
        GithubToken:     userToken,
        UseLoggedInUser: copilot.Bool(false),
    })
}

// Usage
client := createClientForUser("USER-ACCESS-TOKEN")
client.Start(ctx)
defer client.Stop()

session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
    SessionID: fmt.Sprintf("user-%s-session", userID),
    Model:     "gpt-4.1",
})
response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Hello!"})

.NET

CopilotClient CreateClientForUser(string userToken) =>
    new CopilotClient(new CopilotClientOptions
    {
        GithubToken = userToken,
        UseLoggedInUser = false,
    });

// Usage
await using var client = CreateClientForUser("USER-ACCESS-TOKEN");
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    SessionId = $"user-{userId}-session",
    Model = "gpt-4.1",
});

var response = await session.SendAndWaitAsync(
    new MessageOptions { Prompt = "Hello!" });

企业和组织访问权限

          GitHub OAuth 自然支持企业方案。 当用户使用GitHub进行身份验证时,将包括他们的组织成员资格和企业关联。

验证组织成员身份

OAuth 后,可以检查用户是否属于组织:

async function verifyOrgMembership(
    token: string,
    requiredOrg: string
): Promise<boolean> {
    const response = await fetch("https://api.github.com/user/orgs", {
        headers: { Authorization: `Bearer ${token}` },
    });
    const orgs = await response.json();
    return orgs.some((org: any) => org.login === requiredOrg);
}

// In your auth flow
const token = await handleOAuthCallback(code);
if (!await verifyOrgMembership(token, "YOUR-ORG")) {
    throw new Error("User is not a member of the required organization");
}
const client = createClientForUser(token);

YOUR-ORG 替换为组织 GitHub 的名称。

企业托管用户(EMU)

对于 托管用户帐户,流是相同的。 EMU 用户像任何其他用户一样通过 GitHub OAuth 进行身份验证,并且会自动强制实施 GitHub 企业策略(IP 限制、SAML SSO)。

// No special SDK configuration needed for EMU
const client = new CopilotClient({
    githubToken: emuUserToken,
    useLoggedInUser: false,
});

支持的令牌类型

令牌前缀来源支持
gho_OAuth 用户访问令牌是的
ghu_
          GitHub App 用户访问令牌 | 是的 |

| github_pat_ | Fine-grained personal access token | 是的 | | ghp_ | Personal access token (classic) | 否(弃用) |

令牌生命周期管理

应用程序负责令牌存储、刷新和过期处理。 SDK 使用你提供的任何令牌 -- 它不管理 OAuth 生命周期。

令牌刷新模式

async function getOrRefreshToken(userId: string): Promise<string> {
    const stored = await tokenStore.get(userId);

    if (stored && !isExpired(stored)) {
        return stored.accessToken;
    }

    if (stored?.refreshToken) {
        const refreshed = await refreshGitHubToken(stored.refreshToken);
        await tokenStore.set(userId, refreshed);
        return refreshed.accessToken;
    }

    throw new Error("User must re-authenticate");
}

多用户模式

每个用户使用自己的令牌获取自己的 SDK 客户端。 这提供最强的隔离。

const clients = new Map<string, CopilotClient>();

function getClientForUser(userId: string, token: string): CopilotClient {
    if (!clients.has(userId)) {
        clients.set(userId, new CopilotClient({
            githubToken: token,
            useLoggedInUser: false,
        }));
    }
    return clients.get(userId)!;
}

局限性

限度详细信息
          **
          Copilot 需要订阅** | 每个用户都需要拥有一个有效的 GitHub Copilot 订阅。 |

| 令牌管理是你的责任 | 必须存储、刷新和处理令牌过期。 | | ** GitHub 需要帐户** | 用户必须具有 GitHub 帐户。 | | 每个用户的速率限制 | 使用情况取决于每个用户的 Copilot 速率限制。 |

后续步骤