Appearance
OAuth 方式让每个用户用自己的 GitHub 账号授权你的应用,使用各自的 Copilot 配额。创建 GitHub OAuth App,实现标准 OAuth 流程,每个用户单独创建 SDK 客户端并传入其 token。SDK 不管理 OAuth 生命周期,需要应用层自行处理 token 刷新。
GitHub Copilot SDK GitHub OAuth 配置:为 SaaS 应用服务多用户
适用场景
- SaaS 应用:服务多个用户,每人用自己的 Copilot 订阅
- 团队工具:部门内多人共用一个工具,各自的 Copilot 配额独立
- 插件/扩展:需要用户授权才能访问 Copilot
前提条件
- 每个用户需要有 GitHub Copilot 订阅(Free / Pro / Pro+)
- 需要在 GitHub 创建一个 OAuth App
第一步:创建 GitHub OAuth App
- 进入 GitHub Settings → Developer settings → OAuth Apps
- 点击 New OAuth App,填写:
- Application name:你的应用名
- Homepage URL:应用首页
- Authorization callback URL:OAuth 回调地址(如
https://your-app.com/auth/github/callback)
- 记录 Client ID 和 Client Secret
第二步:实现 OAuth 流程
typescript
import express from 'express'
const app = express()
// 步骤 1:引导用户到 GitHub 授权页
app.get('/auth/github', (req, res) => {
const authUrl = new URL('https://github.com/login/oauth/authorize')
authUrl.searchParams.set('client_id', process.env.GITHUB_CLIENT_ID!)
authUrl.searchParams.set('scope', 'copilot') // 申请 Copilot 访问权限
authUrl.searchParams.set('state', generateCsrfToken(req))
res.redirect(authUrl.toString())
})
// 步骤 2:处理 OAuth 回调,换取 access token
app.get('/auth/github/callback', async (req, res) => {
const { code, state } = req.query
// 验证 CSRF state
if (!validateCsrfToken(req, state as string)) {
return res.status(403).send('Invalid state')
}
// 用 code 换取 access token
const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
method: 'POST',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: process.env.GITHUB_CLIENT_ID,
client_secret: process.env.GITHUB_CLIENT_SECRET,
code
})
})
const { access_token } = await tokenResponse.json()
// 存储用户 token(数据库/Session)
await saveUserToken(req.session.userId, access_token)
res.redirect('/dashboard')
})第三步:为每个用户创建 SDK 客户端
typescript
import { createSession } from '@github/copilot-sdk'
// 每个用户请求单独创建 Session,传入该用户的 token
async function handleUserRequest(userId: string, userPrompt: string) {
const userToken = await getUserToken(userId)
const session = await createSession({
auth: {
type: 'oauth',
clientId: process.env.GITHUB_CLIENT_ID!,
token: userToken
}
})
const response = await session.sendPrompt({
messages: [{ role: 'user', content: userPrompt }]
})
return response.content
}多用户隔离
每个用户使用独立的 Session,确保用户之间完全隔离:
typescript
// 推荐:用 userId 作为 sessionId 前缀,便于管理
const session = await createSession({
auth: { type: 'oauth', token: userToken },
sessionId: `user-${userId}-${Date.now()}`
})验证用户的组织归属(可选)
如果需要限制只有特定组织成员才能访问:
typescript
async function isUserInOrg(token: string, orgName: 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 === orgName)
}
// 在创建 Session 前检查
if (!await isUserInOrg(userToken, 'your-org-name')) {
throw new Error('只有 your-org-name 组织成员才能使用此功能')
}Token 类型说明
支持的 GitHub token 前缀:
| 前缀 | 类型 |
|---|---|
gho_ | OAuth access token |
ghu_ | User-to-server token(GitHub App) |
github_pat_ | Fine-grained Personal Access Token |
常见问题
Q: Token 过期后怎么处理?
A: GitHub OAuth token 没有过期时间,除非用户主动撤销授权。但 Fine-grained PAT 有过期时间,需要定期提醒用户更新。SDK 不管理 token 生命周期,检测到 401 错误时需要引导用户重新授权。
Q: 同一用户可以有多个并发 Session 吗?
A: 技术上可以,但每个 Session 消耗该用户的 Copilot Premium Request 配额。如果并发 Session 过多,可能导致用户额度快速耗尽。
Q: 是否需要存储 access_token?
A: 是的。OAuth token 只在换取时返回一次,如果不存储就无法复用。建议加密后存入数据库,不要存明文。