目标

给 new-api 站点开社交登录(GitHub / LinuxDO / Discord / Telegram / 微信 / OIDC / 自定义 OAuth)。

原理

new-api 自带所有 provider 的实现,不需要插件。开一个 provider 只需三步:① 去对方平台注册应用拿 Client ID + Secret ② 把值写进 options 表 ③ 打开 XxxOAuthEnabled。

支持的内置 provider(oauth/ 目录,注册名见各文件首行的 Register("<slug>", ...)):

providerslug需要的凭据
GitHubgithubOAuth App 的 Client ID + Client Secret
LinuxDOlinuxdolinux.do 的 Client ID + Secret
DiscorddiscordDiscord 应用的 Client ID + Secret
TelegramtelegramBot token(走 Bot 登录,不是 OAuth)
微信wechat微信开放平台「网站应用」,需企业认证
OIDCoidc任意 OIDC 提供方的 endpoint + Client ID + Secret
自定义任意 slugGeneric OAuth provider

回调地址(最容易填错的地方)

前端在 web/src/features/auth/hooks/use-oauth-login.ts 拼出回调地址:

const redirectUri = `${window.location.origin}/oauth/${provider.slug}`

所以对 https://<域名> 上的 github:

https://<域名>/oauth/github

在对方平台的「Authorization callback URL / Redirect URI」里必须一字不差:https 开头、结尾没有斜杠、路径小写。差一个字符就会报 redirect_uri_mismatch,用户点按钮直接失败。

注意回调是前端路由(web/src/routes/oauth/$provider.tsx),前端页面再调后端 GET /api/oauth/:provider 完成换取用户信息。

GitHub OAuth App 创建步骤

入口:https://github.com/settings/applications/new

(手动路径:头像 → Settings → 左下角 Developer settings → OAuth Apps → New OAuth App。)

别用「GitHub App」那个页面。 Developer settings 下有 GitHub Apps 和 OAuth Apps 两个入口,长得很像,但完全不同:GitHub App 要配权限、Webhook、事件订阅、安装范围,字段多;new-api 走的是经典 OAuth 流程(github.com/login/oauth/access_token + api.github.com/user),对应 OAuth App。判别方法:OAuth App 页面只有 4 个输入框,一个勾选框都没有。

OAuth App 表单只填三格:

字段值
Application name显示给用户的名字,如 6767 API
Homepage URLhttps://<域名>
Authorization callback URLhttps://<域名>/oauth/github

点 Register application 后,页面顶部给出 Client ID;下方 Client secrets 区块点 Generate a new client secret 得到 Client Secret——只显示一次,关掉页面只能重新生成。

写入 new-api

INSERT INTO options(key,value) VALUES('GitHubOAuthEnabled','true')
  ON CONFLICT(key) DO UPDATE SET value=excluded.value;
INSERT INTO options(key,value) VALUES('GitHubClientId','<Client ID>')
  ON CONFLICT(key) DO UPDATE SET value=excluded.value;
INSERT INTO options(key,value) VALUES('GitHubClientSecret','<Client Secret>')
  ON CONFLICT(key) DO UPDATE SET value=excluded.value;

选项键名(model/option.go):GitHubOAuthEnabled / GitHubClientId / GitHubClientSecret;其他 provider 同理,如 LinuxDOOAuthEnabled、DiscordOAuthEnabled 等。

改完不用重启,SyncFrequency(默认 60 秒)会把 options 刷进内存。打开 ai.6767.chat 的后台设置页也能改同样的值。

验证方法

分三层,越往后越接近真实:

# 1) 状态接口有没有下发(前端靠这个决定显不显示按钮)
curl -s http://127.0.0.1:3000/api/status | python3 -c "import sys,json;d=json.load(sys.stdin)['data'];print(d.get('github_oauth'), d.get('github_client_id'))"
# 期望: True Ov23li...

# 2) 回调路由接住了吗(用假 code,期望业务错而不是 404)
curl -s "https://127.0.0.1/api/oauth/github?code=fake&state=fake" -H "Host: <域名>"
# 期望: {"message":"State parameter is empty or mismatched","success":false}
# 若是 404,说明路由没挂上;若是别的错,看 message

3) 让对方平台自己判 Client ID 和回调地址——这一步比在自己机器上猜可靠得多。直接用浏览器打开授权地址:

https://github.com/login/oauth/authorize?client_id=<Client ID>&scope=user:email&state=probe&redirect_uri=<URL编码后的回调地址>
  • 页面显示 Sign in to GitHub / to continue to <应用名> → Client ID 有效、回调地址匹配、应用名正确,三件事一次验完
  • 显示 "redirect_uri mismatch" → 回调地址跟平台上注册的不一致
  • 显示 "Application not found" 之类 → Client ID 错了

最后一步(只能人工做):真浏览器打开 /sign-up 点「Continue with GitHub」,用自己的账号走一遍完整往返。

坑

1. GitHub OAuth 注册会绕过邮箱域名白名单,且照样拿新用户赠送额度

OAuth 建用户走的是 controller/oauth.go 的 findOrCreateOAuthUser,那条路只调 EnsureEmailAvailable()(查邮箱是否已被占用),不调 ValidateAccountEmail()(域名白名单在这一层)。所以 provider 给的邮箱不会被白名单过滤。

同时它走 user.InsertWithTx(),里面 user.Quota = common.QuotaForNewUser —— 新用户赠送额度照给。

结论:开了社交登录,等于在"邮箱白名单"这堵墙上开了一道门。只是批量注册 GitHub 号比批量注册临时邮箱难得多,门比窗窄。

2. LinuxDO 可以设「最低信任等级」,比 GitHub 更防脚本

linuxdo_minimum_trust_level 可以要求用户的 LinuxDO 信任等级达到 N 级才放行。新注册的 LinuxDO 号等级是 0,刷号的连门都进不来。这是内置 provider 里唯一自带"账号年龄/信誉"门槛的。想要社交登录又怕被刷,优先选它。

3. Client Secret 只在生成时显示一次

GitHub 页面上那串只显示一次,复制失败(比如浏览器插件把页面的 JS 掐了导致复制按钮失灵)就只能重新生成一个,旧的作废。

4. Ov23li... 也是 OAuth App 的 Client ID

GitHub 较新的 OAuth App Client ID 是这个前缀(Ov23li...),不是老式的 20 位纯十六进制。别因为前缀不像老格式就怀疑拿错了应用类型——用上面第 3 条的方法实测最快。

适用边界

  • 针对 new-api v1.0.0-rc.40(QuantumNous/new-api);slug、选项键名、回调路径可能随版本变化,改前先在源码里确认。
  • 平台侧界面会变;GitHub 的 OAuth App 创建入口 2026-09 实测仍在 settings/applications/new。
  • 微信登录需要微信开放平台的网站应用,个人开发者做不了,要企业认证。

本次实例(6767 API / la,2026-09-24)

在 ai.6767.chat 上开了 GitHub 登录。OAuth App 名 6767 API,回调 https://ai.6767.chat/oauth/github,Client ID Ov23li...(20 位),Client Secret 40 位十六进制。凭据写在 options 表的 GitHubClientId / GitHubClientSecret。实测授权地址能打开并显示「to continue to 6767 API」,说明 Client ID 与回调地址均被 GitHub 接受。

关联


本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/AI apps