关于 oauth
面向 Portless 用户的 OAuth 开发指南,介绍如何使用有效的本地域名通过提供商的重定向 URI 校验,并配置常见提供商和认证库。
主要功能
- 01为 Portless 配置有效 TLD
- 02登记提供商重定向 URI
- 03设置认证库回调 URL
- 04排查重定向地址不匹配
适用场景
- 01在本地应用测试 Google OAuth
- 02本地开发 Apple Sign In
- 03统一团队环境中的回调地址
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vercel-labs/ portless --skill oauth安装后在 Claude Code 中输入/oauth确认已加载。
详细介绍
使用 Portless 配置 OAuth
OAuth 提供商会根据域名规则验证重定向 URI。大多数提供商不允许使用 .localhost 子域名,因为它们不在 Public Suffix List 中,或被明确屏蔽。Portless 可通过 --tld 让应用使用真实、有效的域名。
问题
Portless 使用默认的 .localhost TLD 时,OAuth 提供商会拒绝类似 http://myapp.localhost:1355/callback 的重定向 URI:
| 提供商 | localhost | .localhost 子域名 | 原因 |
|---|---|---|---|
| 允许 | 拒绝 | 不在其捆绑的 PSL 中 | |
| Apple | 拒绝 | 拒绝 | 完全不允许 localhost |
| Microsoft | 允许 | 允许 | 对 localhost 的限制较宽松 |
| 允许 | 视情况而定 | 必须逐一精确注册每个 URI | |
| GitHub | 允许 | 允许 | 限制较宽松 |
Google 和 Apple 的限制最严格。Microsoft 和 GitHub 对 localhost 的限制较宽松。
解决方法
使用有效的 TLD,让重定向 URI 通过提供商验证:
portless proxy start --tld dev
portless myapp next dev
# -> https://myapp.dev
Public Suffix List 中的任何 TLD 都可使用:.dev、.app、.com、.io 等。
使用你拥有的域名
像 .dev 这样的裸 TLD 意味着 myapp.dev 可能与真实域名冲突。请使用你所控制域名下的多级 TLD,这样应用名称就能保持简洁,而域名结构则放在 TLD 中:
portless proxy start --tld local.yourcompany.dev
portless myapp next dev
# -> https://myapp.local.yourcompany.dev
这样可以确保不会有出站流量访问你不拥有的内容。对于团队,可设置通配符 DNS 记录(*.local.yourcompany.dev -> 127.0.0.1),这样每位开发者都无需配置 /etc/hosts 即可解析域名,并且所有开发者在提供商控制台中使用相同的重定向 URI。
提供商配置
- 前往 Google Cloud Console > 凭据
- 创建或编辑 OAuth 2.0 客户端 ID(Web 应用)
- 将 Portless 域名添加到已获授权的 JavaScript 来源:
https://myapp.dev - 将回调地址添加到已获授权的重定向 URI:
https://myapp.dev/api/auth/callback/google
Google 会根据 Public Suffix List 验证域名。域名必须以已识别的 TLD 结尾。.localhost 子域名无法通过此检查;.dev、.app、.com 等均可通过。
.dev 和 .app 要求使用 HTTPS(已预加载 HSTS)。Portless 会通过 --https 自动处理。
Apple
Apple Sign In 完全不允许使用 localhost 或 IP 地址。
- 前往 Apple Developer > 证书、标识符与配置文件
- 注册 Services ID
- 配置 Sign In with Apple,将 Portless 域名添加为返回 URL:
https://myapp.dev/api/auth/callback/apple
域名必须是真实且可公开解析的域名。由于 Portless 会在本地将域名映射到 127.0.0.1,浏览器可以解析该域名,但 Apple 的服务器端验证也可能要求该域名能够公开解析。如果 Apple 拒绝该域名,请为开发子域名添加指向 127.0.0.1 的公共 DNS A 记录。
Microsoft(Entra / Azure AD)
- 前往 Azure Portal > 应用注册
- 创建或编辑应用注册
- 在身份验证下,添加一个 Web 重定向 URI:
https://myapp.dev/api/auth/callback/azure-ad
Microsoft 允许开发环境使用任何端口的 http://localhost。在大多数情况下,它也接受 .localhost 子域名。为了让不同提供商之间保持一致,仍建议在 Portless 中使用自定义 TLD。
Facebook(Meta)
- 前往 Meta for Developers > App Dashboard
- 在 Facebook Login > Settings 下,将无端口 URL 添加到 Valid OAuth Redirect URIs:
https://myapp.dev/api/auth/callback/facebook
Facebook 要求逐一精确注册每个重定向 URI(不支持通配符)。默认启用的 Strict Mode 会强制进行精确匹配。
GitHub
- 前往 GitHub Developer Settings > OAuth Apps
- 设置 Authorization callback URL:
https://myapp.dev/api/auth/callback/github
GitHub 对 localhost 和子域名的要求较宽松。并非必须使用自定义 TLD,但这样可以让配置保持一致。
身份验证库配置
NextAuth / Auth.js
将 NEXTAUTH_URL 设置为与无端口域名一致:
NEXTAUTH_URL=https://myapp.dev
NextAuth 会使用此值构建回调 URL。如果未设置,回调可能会使用 localhost,导致不匹配。
Passport.js
将每个策略中的 callbackURL 设置为使用无端口域名:
new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.BASE_URL + "/auth/google/callback",
});
在环境中设置 BASE_URL=https://myapp.dev。
通用 / 手动配置
读取无端口注入到子进程中的 PORTLESS_URL 环境变量:
const baseUrl = process.env.PORTLESS_URL || "http://localhost:3000";
const callbackUrl = `${baseUrl}/auth/callback`;
故障排查
“redirect_uri_mismatch”或“invalid redirect URI”
OAuth 流程期间发送的重定向 URI 与在提供商处注册的 URI 不匹配。请检查:
- 提供商注册的重定向 URI 与无端口域名完全一致(协议、主机、路径)
NEXTAUTH_URL或等效变量已设置为无端口 URL(而非localhost)- 代理使用了正确的 TLD 运行(运行
portless list进行验证)
提供商要求 HTTPS
.dev 和 .app TLD 已预加载 HSTS,因此浏览器会强制使用 HTTPS。启动代理:
portless proxy start --tld dev
无端口默认使用 443 端口上的 HTTPS(会自动通过 sudo 提权)。运行 portless trust 将本地 CA 添加到系统信任存储中,以消除浏览器警告。
Apple 拒绝该域名
Apple 可能要求该域名可通过公网解析。为你的开发子域名添加一条指向 127.0.0.1 的 DNS A 记录:
myapp.local.yourcompany.dev A 127.0.0.1
或者使用通配符:*.local.yourcompany.dev A 127.0.0.1。
登录后回调转到错误的 URL
身份验证库使用 localhost 而非无端口域名构建回调 URL。设置相应的环境变量:
- NextAuth:
NEXTAUTH_URL=https://myapp.dev - Auth.js v5:
AUTH_URL=https://myapp.dev - 手动配置:
PORTLESS_URL会自动注入;将其用作基础 URL
示例
请参阅 examples/google-oauth,了解一个使用 --tld dev 的 Next.js + NextAuth + Google OAuth 完整可运行示例。