{"meta":{"title":"将 GitHub OAuth 与 Copilot SDK 配合使用","intro":"让用户使用其 GitHub 帐户进行身份验证，以便通过应用程序使用 GitHub Copilot 。","product":"GitHub Copilot","breadcrumbs":[{"href":"/zh/copilot","title":"GitHub Copilot"},{"href":"/zh/copilot/how-tos","title":"操作方法"},{"href":"/zh/copilot/how-tos/copilot-sdk","title":"Copilot SDK"},{"href":"/zh/copilot/how-tos/copilot-sdk/set-up-copilot-sdk","title":"设置 Copilot SDK"},{"href":"/zh/copilot/how-tos/copilot-sdk/set-up-copilot-sdk/github-oauth","title":"GitHub OAuth"}],"documentType":"article"},"body":"# 将 GitHub OAuth 与 Copilot SDK 配合使用\n\n让用户使用其 GitHub 帐户进行身份验证，以便通过应用程序使用 GitHub Copilot 。\n\n> \\[!NOTE]\n\n```\n          Copilot SDK 当前处于 技术预览版. 功能和可用性可能会发生更改。\n```\n\n在您的应用程序中直接提供GitHub帐户身份验证，以连接用户到GitHub Copilot。\n\n```\n          **最适合：** 多用户应用、具有组织访问控制的内部工具、SaaS 产品和用户已有 GitHub 帐户的应用。\n```\n\n## 工作原理\n\n```\n          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)。\n\n          **主要特征：**\n```\n\n* 每个用户使用自己的 GitHub 帐户进行身份验证。\n* Copilot 使用情况按每个用户的订阅计费。\n* 支持 GitHub 组织和企业帐户。\n* 你的应用永远不会处理模型 API 密钥-GitHub 管理所有内容。\n\n## 步骤 1：创建 GitHub OAuth 应用\n\n1. <c1>转到“设置”>“开发人员设置”>“OAuth 应用”>“新的 OAuth 应用”<c0 />。 对于组织，请转到 **组织设置>开发人员设置**。\n2. 填写以下字段：\n   * **应用程序名称**：应用的名称。\n   * **主页 URL**：应用的 URL。\n   * **授权回调 URL**：您的 OAuth 回调终结点（例如 `https://YOUR-APP.com/auth/callback`）。 将 `YOUR-APP.com` 替换为你的域。\n3. 记下 **客户端 ID** 并生成 **客户端密码**。\n\n> \\[!NOTE]\n\n```\n          GitHub Apps 和 OAuth 应用都可以与 SDK 一起使用。 \n```\n\n```\n          GitHub Apps 提供更细致的权限控制，建议用于新项目。 OAuth 应用设置更简单。 从 SDK 的角度来看，令牌流是相同的。\n```\n\n## 步骤 2：实现 OAuth 流\n\n应用程序处理标准 GitHub OAuth 流。 下面显示了服务器端令牌交换：\n\n```typescript\n// Server-side: exchange authorization code for user token\nasync function handleOAuthCallback(code: string): Promise<string> {\n    const response = await fetch(\"https://github.com/login/oauth/access_token\", {\n        method: \"POST\",\n        headers: {\n            \"Content-Type\": \"application/json\",\n            Accept: \"application/json\",\n        },\n        body: JSON.stringify({\n            client_id: process.env.GITHUB_CLIENT_ID,\n            client_secret: process.env.GITHUB_CLIENT_SECRET,\n            code,\n        }),\n    });\n\n    const data = await response.json();\n    return data.access_token; // gho_xxxx or ghu_xxxx\n}\n```\n\n## 步骤 3：将令牌传递给 SDK\n\n为每个经过身份验证的用户创建 SDK 客户端，并传递其令牌。\n\n### Node.js/TypeScript\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\n// Create a client for an authenticated user\nfunction createClientForUser(userToken: string): CopilotClient {\n    return new CopilotClient({\n        githubToken: userToken,\n        useLoggedInUser: false,  // Don't fall back to CLI sign-in\n    });\n}\n\n// Usage\nconst client = createClientForUser(\"USER-ACCESS-TOKEN\");\nconst session = await client.createSession({\n    sessionId: `user-${userId}-session`,\n    model: \"gpt-4.1\",\n});\n\nconst response = await session.sendAndWait({ prompt: \"Hello!\" });\n```\n\n将 `USER-ACCESS-TOKEN` 替换为用户的 OAuth 访问令牌（例如 `gho_xxxx`）。\n\n### Python\n\n```python\nfrom copilot import CopilotClient, PermissionHandler\n\ndef create_client_for_user(user_token: str) -> CopilotClient:\n    return CopilotClient({\n        \"github_token\": user_token,\n        \"use_logged_in_user\": False,\n    })\n\n# Usage\nclient = create_client_for_user(\"USER-ACCESS-TOKEN\")\nawait client.start()\n\nsession = await client.create_session(\n    on_permission_request=PermissionHandler.approve_all,\n    model=\"gpt-4.1\",\n    session_id=f\"user-{user_id}-session\",\n)\n\nresponse = await session.send_and_wait({\"prompt\": \"Hello!\"})\n```\n\n### Go\n\n```golang\nfunc createClientForUser(userToken string) *copilot.Client {\n    return copilot.NewClient(&copilot.ClientOptions{\n        GithubToken:     userToken,\n        UseLoggedInUser: copilot.Bool(false),\n    })\n}\n\n// Usage\nclient := createClientForUser(\"USER-ACCESS-TOKEN\")\nclient.Start(ctx)\ndefer client.Stop()\n\nsession, _ := client.CreateSession(ctx, &copilot.SessionConfig{\n    SessionID: fmt.Sprintf(\"user-%s-session\", userID),\n    Model:     \"gpt-4.1\",\n})\nresponse, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: \"Hello!\"})\n```\n\n### .NET\n\n```csharp\nCopilotClient CreateClientForUser(string userToken) =>\n    new CopilotClient(new CopilotClientOptions\n    {\n        GithubToken = userToken,\n        UseLoggedInUser = false,\n    });\n\n// Usage\nawait using var client = CreateClientForUser(\"USER-ACCESS-TOKEN\");\nawait using var session = await client.CreateSessionAsync(new SessionConfig\n{\n    SessionId = $\"user-{userId}-session\",\n    Model = \"gpt-4.1\",\n});\n\nvar response = await session.SendAndWaitAsync(\n    new MessageOptions { Prompt = \"Hello!\" });\n```\n\n## 企业和组织访问权限\n\n```\n          GitHub OAuth 自然支持企业方案。 当用户使用GitHub进行身份验证时，将包括他们的组织成员资格和企业关联。\n```\n\n### 验证组织成员身份\n\nOAuth 后，可以检查用户是否属于组织：\n\n```typescript\nasync function verifyOrgMembership(\n    token: string,\n    requiredOrg: string\n): Promise<boolean> {\n    const response = await fetch(\"https://api.github.com/user/orgs\", {\n        headers: { Authorization: `Bearer ${token}` },\n    });\n    const orgs = await response.json();\n    return orgs.some((org: any) => org.login === requiredOrg);\n}\n\n// In your auth flow\nconst token = await handleOAuthCallback(code);\nif (!await verifyOrgMembership(token, \"YOUR-ORG\")) {\n    throw new Error(\"User is not a member of the required organization\");\n}\nconst client = createClientForUser(token);\n```\n\n将 `YOUR-ORG` 替换为组织 GitHub 的名称。\n\n### 企业托管用户（EMU）\n\n对于 托管用户帐户，流是相同的。 EMU 用户像任何其他用户一样通过 GitHub OAuth 进行身份验证，并且会自动强制实施 GitHub 企业策略（IP 限制、SAML SSO）。\n\n```typescript\n// No special SDK configuration needed for EMU\nconst client = new CopilotClient({\n    githubToken: emuUserToken,\n    useLoggedInUser: false,\n});\n```\n\n## 支持的令牌类型\n\n| 令牌前缀   | 来源           | 支持 |\n| ------ | ------------ | -- |\n| `gho_` | OAuth 用户访问令牌 | 是的 |\n| `ghu_` |              |    |\n\n```\n          GitHub App 用户访问令牌 | 是的 |\n```\n\n\\| `github_pat_` | Fine-grained personal access token                           | 是的 |\n\\| `ghp_` | Personal access token (classic)                                      | 否（弃用） |\n\n## 令牌生命周期管理\n\n应用程序负责令牌存储、刷新和过期处理。 SDK 使用你提供的任何令牌 -- 它不管理 OAuth 生命周期。\n\n### 令牌刷新模式\n\n```typescript\nasync function getOrRefreshToken(userId: string): Promise<string> {\n    const stored = await tokenStore.get(userId);\n\n    if (stored && !isExpired(stored)) {\n        return stored.accessToken;\n    }\n\n    if (stored?.refreshToken) {\n        const refreshed = await refreshGitHubToken(stored.refreshToken);\n        await tokenStore.set(userId, refreshed);\n        return refreshed.accessToken;\n    }\n\n    throw new Error(\"User must re-authenticate\");\n}\n```\n\n## 多用户模式\n\n### 每个用户一个客户端（建议）\n\n每个用户使用自己的令牌获取自己的 SDK 客户端。 这提供最强的隔离。\n\n```typescript\nconst clients = new Map<string, CopilotClient>();\n\nfunction getClientForUser(userId: string, token: string): CopilotClient {\n    if (!clients.has(userId)) {\n        clients.set(userId, new CopilotClient({\n            githubToken: token,\n            useLoggedInUser: false,\n        }));\n    }\n    return clients.get(userId)!;\n}\n```\n\n## 局限性\n\n| 限度   | 详细信息 |\n| ---- | ---- |\n| \\*\\* |      |\n\n```\n          Copilot 需要订阅** | 每个用户都需要拥有一个有效的 GitHub Copilot 订阅。 |\n```\n\n\\| **令牌管理是你的责任** | 必须存储、刷新和处理令牌过期。 |\n\\| \\*\\*\nGitHub 需要帐户\\*\\* | 用户必须具有 GitHub 帐户。 |\n\\| **每个用户的速率限制** | 使用情况取决于每个用户的 Copilot 速率限制。 |\n\n## 后续步骤\n\n* 若要在服务器上运行 SDK，请参阅 [为后端服务设置 Copilot SDK](/zh/copilot/how-tos/copilot-sdk/set-up-copilot-sdk/backend-services)。\n* 若要处理多个并发用户，请参阅 [扩展 Copilot SDK 的部署](/zh/copilot/how-tos/copilot-sdk/set-up-copilot-sdk/scaling)。\n* 有关安装和第一条消息，请参阅 [开始使用 Copilot SDK](/zh/copilot/how-tos/copilot-sdk/sdk-getting-started)。"}