oauth-integrations by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill oauth-integrations在 Cloudflare Workers 及其他边缘运行时中实现 GitHub 和 Microsoft OAuth。
GitHub API 有严格的要求,与其他提供商不同。
| 请求头 | 要求 |
|---|---|
User-Agent | 必需 - 缺少此头将返回 403 |
Accept | 推荐使用 application/vnd.github+json |
const resp = await fetch('https://api.github.com/user', {
headers: {
Authorization: `Bearer ${accessToken}`,
'User-Agent': 'MyApp/1.0', // 必需!
'Accept': 'application/vnd.github+json',
},
});
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
GitHub 用户可以将邮箱设置为私有(/user 接口返回 email: null)。
if (!userData.email) {
const emails = await fetch('https://api.github.com/user/emails', { headers })
.then(r => r.json());
userData.email = emails.find(e => e.primary && e.verified)?.email;
}
需要 user:email 权限范围。
令牌交换默认返回表单编码格式。添加 Accept 请求头以获取 JSON 响应:
const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json', // 获取 JSON 响应
},
body: new URLSearchParams({ code, client_id, client_secret, redirect_uri }),
});
| 问题 | 解决方案 |
|---|---|
| 回调 URL | 必须完全匹配 - 不支持通配符,不支持子目录匹配 |
| 令牌交换返回表单编码格式 | 添加 'Accept': 'application/json' 请求头 |
| 令牌不会过期 | 无需刷新流程,但令牌被撤销后需要完全重新认证 |
MSAL.js 依赖以下环境:
Cloudflare 的 V8 隔离运行时两者都不具备。请改用手动 OAuth 方案:
jose 库进行 JWT 验证// 用于获取用户身份信息(邮箱、姓名、头像)
const scope = 'openid email profile User.Read';
// 用于获取刷新令牌(长会话)
const scope = 'openid email profile User.Read offline_access';
关键点:User.Read 是访问 Microsoft Graph /me 端点所必需的。缺少此权限,令牌交换会成功,但获取用户信息时将返回 403。
// Microsoft Graph /me 端点
const resp = await fetch('https://graph.microsoft.com/v1.0/me', {
headers: { Authorization: `Bearer ${accessToken}` },
});
// 邮箱可能位于不同字段中
const email = data.mail || data.userPrincipalName;
| 租户值 | 可登录用户 |
|---|---|
common | 任何 Microsoft 账户(个人 + 工作) |
organizations | 仅限工作/学校账户 |
consumers | 仅限个人 Microsoft 账户 |
{tenant-id} | 仅限特定组织 |
/callback 和 /admin/callback| 令牌类型 | 默认生命周期 | 说明 |
|---|---|---|
| 访问令牌 | 60-90 分钟 | 可通过令牌生命周期策略配置 |
| 刷新令牌 | 90 天 | 密码更改时撤销 |
| ID 令牌 | 60 分钟 | 与访问令牌相同 |
最佳实践:对于超过 1 小时的会话,始终请求 offline_access 权限范围并实现刷新令牌流程。
| 如果 Claude 建议... | 请改用... |
|---|---|
| GitHub fetch 时不带 User-Agent | 添加 'User-Agent': 'AppName/1.0'(必需) |
| 在 Workers 中使用 MSAL.js | 手动 OAuth + jose 库进行 JWT 验证 |
| Microsoft 权限范围中缺少 User.Read | 添加 User.Read 权限范围 |
| 仅从令牌声明中获取邮箱 | 使用 Graph /me 端点 |
| 错误 | 原因 | 修复方法 |
|---|---|---|
| 403 Forbidden | 缺少 User-Agent 请求头 | 添加 User-Agent 请求头 |
email: null | 用户邮箱设为私有 | 使用 user:email 权限范围获取 /user/emails |
| 错误 | 原因 | 修复方法 |
|---|---|---|
| AADSTS50058 | 静默认证失败 | 使用交互式流程 |
| AADSTS700084 | 刷新令牌已过期 | 重新认证用户 |
| Graph /me 返回 403 | 缺少 User.Read 权限范围 | 在权限范围中添加 User.Read |
每周安装量
356
代码仓库
GitHub 星标数
652
首次出现
2026 年 1 月 20 日
安全审计
安装于
claude-code290
gemini-cli242
opencode234
cursor226
antigravity214
codex211
Implement GitHub and Microsoft OAuth in Cloudflare Workers and other edge runtimes.
GitHub API has strict requirements that differ from other providers.
| Header | Requirement |
|---|---|
User-Agent | REQUIRED - Returns 403 without it |
Accept | application/vnd.github+json recommended |
const resp = await fetch('https://api.github.com/user', {
headers: {
Authorization: `Bearer ${accessToken}`,
'User-Agent': 'MyApp/1.0', // Required!
'Accept': 'application/vnd.github+json',
},
});
GitHub users can set email to private (/user returns email: null).
if (!userData.email) {
const emails = await fetch('https://api.github.com/user/emails', { headers })
.then(r => r.json());
userData.email = emails.find(e => e.primary && e.verified)?.email;
}
Requires user:email scope.
Token exchange returns form-encoded by default. Add Accept header for JSON:
const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json', // Get JSON response
},
body: new URLSearchParams({ code, client_id, client_secret, redirect_uri }),
});
| Issue | Solution |
|---|---|
| Callback URL | Must be EXACT - no wildcards, no subdirectory matching |
| Token exchange returns form-encoded | Add 'Accept': 'application/json' header |
| Tokens don't expire | No refresh flow needed, but revoked = full re-auth |
MSAL.js depends on:
Cloudflare's V8 isolate runtime has neither. Use manual OAuth instead:
jose library// For user identity (email, name, profile picture)
const scope = 'openid email profile User.Read';
// For refresh tokens (long-lived sessions)
const scope = 'openid email profile User.Read offline_access';
Critical : User.Read is required for Microsoft Graph /me endpoint. Without it, token exchange succeeds but user info fetch returns 403.
// Microsoft Graph /me endpoint
const resp = await fetch('https://graph.microsoft.com/v1.0/me', {
headers: { Authorization: `Bearer ${accessToken}` },
});
// Email may be in different fields
const email = data.mail || data.userPrincipalName;
| Tenant Value | Who Can Sign In |
|---|---|
common | Any Microsoft account (personal + work) |
organizations | Work/school accounts only |
consumers | Personal Microsoft accounts only |
{tenant-id} | Specific organization only |
/callback and /admin/callback| Token Type | Default Lifetime | Notes |
|---|---|---|
| Access token | 60-90 minutes | Configurable via token lifetime policies |
| Refresh token | 90 days | Revoked on password change |
| ID token | 60 minutes | Same as access token |
Best Practice : Always request offline_access scope and implement refresh token flow for sessions longer than 1 hour.
| If Claude suggests... | Use instead... |
|---|---|
| GitHub fetch without User-Agent | Add 'User-Agent': 'AppName/1.0' (REQUIRED) |
| Using MSAL.js in Workers | Manual OAuth + jose for JWT validation |
| Microsoft scope without User.Read | Add User.Read scope |
| Fetching email from token claims only | Use Graph /me endpoint |
| Error | Cause | Fix |
|---|---|---|
| 403 Forbidden | Missing User-Agent header | Add User-Agent header |
email: null | User has private email | Fetch /user/emails with user:email scope |
| Error | Cause | Fix |
|---|---|---|
| AADSTS50058 | Silent auth failed | Use interactive flow |
| AADSTS700084 | Refresh token expired | Re-authenticate user |
| 403 on Graph /me | Missing User.Read scope | Add User.Read to scopes |
Weekly Installs
356
Repository
GitHub Stars
652
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
claude-code290
gemini-cli242
opencode234
cursor226
antigravity214
codex211
Azure 升级评估与自动化工具 - 轻松迁移 Functions 计划、托管层级和 SKU
68,100 周安装
项目开发指南技能示例:Next.js + FastAPI + Claude AI 全栈架构与代码规范
256 周安装
Skill Auditor:AI技能安全审计工具,6步协议检测恶意代码与权限风险
256 周安装
extract 技能:自动化网页数据抓取工具,生成Playwright脚本和JSON/CSV数据
257 周安装
阿里云OSS对象存储管理工具ossutil 2.0使用指南:安装、配置与常用命令
257 周安装
自主代理模式:构建AI编码代理的设计模式与架构指南
257 周安装
macOS磁盘清理工具 - 安全智能分析回收存储空间 | macOS Cleaner
257 周安装