{"meta":{"title":"GitHub OAuth 设置","intro":"让用户使用其GitHub帐户进行身份验证，以便通过应用程序使用Copilot。 这支持个人帐户、组织成员身份和企业标识。","product":"GitHub Copilot","breadcrumbs":[{"href":"/zh/enterprise-cloud@latest/copilot","title":"GitHub Copilot"},{"href":"/zh/enterprise-cloud@latest/copilot/how-tos","title":"操作方法"},{"href":"/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk","title":"Copilot SDK"},{"href":"/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup","title":"设置 Copilot SDK"},{"href":"/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/github-oauth","title":"GitHub OAuth"}],"documentType":"article"},"body":"# GitHub OAuth 设置\n\n让用户使用其GitHub帐户进行身份验证，以便通过应用程序使用Copilot。 这支持个人帐户、组织成员身份和企业标识。\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n**最适合：** 多用户应用、具有组织级访问控制的内部工具、SaaS 产品、用户拥有 GitHub 账户的应用。\n\n## 工作原理\n\n创建GitHub OAuth 应用（或GitHub应用），用户对其进行授权，并将其访问令牌传递给 SDK。 Copilot 使用其 Copilot 订阅代表每个经过身份验证的用户发出请求。\n\n![关系图：显示描述的过程的序列图。](/assets/images/help/copilot/copilot-sdk/setup-github-oauth-diagram-0.png)\n\n**主要特征：**\n\n* 每个用户使用自己的GitHub帐户进行身份验证\n* Copilot 使用费用将计入每个用户的订阅\n* 支持GitHub组织和企业帐户\n* 你的应用永远不会处理模型 API 密钥 - GitHub管理所有内容\n\n## Architecture\n\n![图示：显示所述流程的流程图。](/assets/images/help/copilot/copilot-sdk/setup-github-oauth-diagram-1.png)\n\n## 步骤 1：创建GitHub OAuth 应用\n\n1. 转到**GitHub设置→开发人员设置→ OAuth 应用→新 OAuth 应用**（或适用于组织：**组织设置→开发人员设置**）\n\n2. 填写：\n   * **应用程序名称**：应用的名称\n   * **主页 URL**：应用的 URL\n   * **授权回调 URL**：您的 OAuth 回调端点（例如 `https://yourapp.com/auth/callback`）\n\n3. 记下 **客户端 ID** 并生成 **客户端密码**\n\n> **GitHub 应用与 OAuth 应用：** 两者都可以。 GitHub应用提供精细的权限，建议用于新项目。 OAuth 应用设置更简单。 从 SDK 的角度来看，令牌流是相同的。\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<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\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 login\n    });\n}\n\n// Usage\nconst client = createClientForUser(\"gho_user_access_token\");\nconst session = await client.createSession({\n    sessionId: `user-${userId}-session`,\n    model: \"gpt-5.4\",\n});\n\nconst response = await session.sendAndWait({ prompt: \"Hello!\" });\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient\nfrom copilot.session import 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(\"gho_user_access_token\")\nawait client.start()\n\nsession = await client.create_session(on_permission_request=PermissionHandler.approve_all, model=\"gpt-5.4\", session_id=f\"user-{user_id}-session\")\n\nresponse = await session.send_and_wait(\"Hello!\")\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\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(\"gho_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-5.4\",\n})\nresponse, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: \"Hello!\"})\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\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(\"gho_user_access_token\");\nawait using var session = await client.CreateSessionAsync(new SessionConfig\n{\n    SessionId = $\"user-{userId}-session\",\n    Model = \"gpt-5.4\",\n});\n\nvar response = await session.SendAndWaitAsync(\n    new MessageOptions { Prompt = \"Hello!\" });\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nimport com.github.copilot.CopilotClient;\nimport com.github.copilot.rpc.*;\n\nCopilotClient createClientForUser(String userToken) throws Exception {\n    var client = new CopilotClient(new CopilotClientOptions()\n        .setGitHubToken(userToken)\n        .setUseLoggedInUser(false)\n    );\n    client.start().get();\n    return client;\n}\n\n// Usage — use try-with-resources to ensure cleanup\nvar userId = \"user1\";\ntry (var client = createClientForUser(\"gho_user_access_token\")) {\n    var session = client.createSession(new SessionConfig()\n        .setSessionId(String.format(\"user-%s-session\", userId))\n        .setModel(\"gpt-5.4\")\n        .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)\n    ).get();\n\n    var response = session.sendAndWait(new MessageOptions()\n        .setPrompt(\"Hello!\")).get();\n}\n```\n\n</div>\n\n</div>\n\n## 企业和组织访问权限\n\nGitHub OAuth 自然支持企业方案。 当用户使用GitHub进行身份验证时，其组织成员资格和企业关联也随之而来。\n\n![图示：显示所述流程的流程图。](/assets/images/help/copilot/copilot-sdk/setup-github-oauth-diagram-2.png)\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, \"my-company\")) {\n    throw new Error(\"User is not a member of the required organization\");\n}\nconst client = createClientForUser(token);\n```\n\n### 企业托管用户（EMU）\n\n对于GitHub企业托管用户，流是相同的 — EMU 用户像任何其他用户一样通过 GitHub OAuth 进行身份验证。 其企业策略（IP 限制、SAML SSO）由 GitHub 自动强制执行。\n\n```typescript\n// No special SDK configuration needed for EMU\n// Enterprise policies are enforced server-side by GitHub\nconst client = new CopilotClient({\n    gitHubToken: emuUserToken,  // Works the same as regular tokens\n    useLoggedInUser: false,\n});\n```\n\n## 支持的令牌类型\n\n| 令牌前缀          | 来源             | 可以用吗？ |\n| ------------- | -------------- | ----- |\n| `gho_`        | OAuth 用户访问令牌   | ✅     |\n| `ghu_`        | GitHub应用用户访问令牌 | ✅     |\n| `github_pat_` | 细粒度的个人访问令牌     | ✅     |\n| `ghp_`        | 经典个人访问令牌       |       |\n| ❌（已弃用）        |                |       |\n\n## 令牌生命周期\n\n![图示：显示所述流程的流程图。](/assets/images/help/copilot/copilot-sdk/setup-github-oauth-diagram-3.png)\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### 共享 CLI，每请求使用不同令牌\n\n为了减小资源占用，你可以运行单个外部 CLI 服务器，并按会话传递令牌。 有关此模式，请参阅 [后端服务设置](/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/backend-services) 。\n\n## 局限性\n\n| Limitation        | 详细信息                    |\n| ----------------- | ----------------------- |\n| **需要 Copilot 订阅** | 每个用户都需要一个有效的 Copilot 订阅 |\n| **令牌管理是你的责任**     | 存储、刷新和处理过期              |\n| 需要**GitHub帐户**    | 用户必须具有GitHub帐户          |\n| **每个用户的速率限制**     | 取决于各用户的 Copilot 速率限制    |\n\n## 何时继续\n\n| 需要                                                                                       | 下一篇指南 |\n| ---------------------------------------------------------------------------------------- | ----- |\n| 没有GitHub帐户的用户                                                                            |       |\n| [BYOK （自带密钥）](/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/auth/byok)         |       |\n| 在服务器上运行 SDK                                                                              |       |\n| [后端服务设置](/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/backend-services) |       |\n| 处理多个并发用户                                                                                 |       |\n| [缩放和多租户](/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/scaling)          |       |\n\n## 后续步骤\n\n* **[Authentication](/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/auth/authenticate)**：完整身份验证方法参考\n* **[后端服务设置](/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/backend-services)**：在服务器端运行 SDK\n* **[缩放和多租户](/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/scaling)**：大规模处理大量用户"}