oauth
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOAuth with Portless
结合Portless使用OAuth
OAuth providers validate redirect URIs against domain rules. subdomains fail on most providers because they are not in the Public Suffix List or are explicitly blocked. Portless fixes this with to serve apps on real, valid domains.
.localhost--tldOAuth提供商会根据域名规则验证重定向URI。子域名在大多数提供商处无法通过验证,因为它们不在公共后缀列表(Public Suffix List,PSL)中,或是被明确阻止。Portless通过参数解决此问题,让应用在真实有效的域名上运行。
.localhost--tldThe Problem
问题描述
When portless uses the default TLD, OAuth providers reject redirect URIs like :
.localhosthttp://myapp.localhost:1355/callback| Provider | | | Reason |
|---|---|---|---|
| Allowed | Rejected | Not in their bundled PSL | |
| Apple | Rejected | Rejected | No localhost at all |
| Microsoft | Allowed | Allowed | Permissive localhost handling |
| Allowed | Varies | Must register each URI exactly | |
| GitHub | Allowed | Allowed | Permissive |
Google and Apple are the strictest. Microsoft and GitHub are more lenient with localhost.
当Portless使用默认的顶级域名(TLD)时,OAuth提供商会拒绝类似这样的重定向URI:
.localhosthttp://myapp.localhost:1355/callback| 提供商 | | | 原因说明 |
|---|---|---|---|
| 允许 | 拒绝 | 不在其内置的PSL列表中 | |
| Apple | 拒绝 | 拒绝 | 完全不支持localhost |
| Microsoft | 允许 | 允许 | 对localhost处理较为宽松 |
| 允许 | 情况不一 | 必须精确注册每个URI | |
| GitHub | 允许 | 允许 | 处理较为宽松 |
Google和Apple的限制最严格,Microsoft和GitHub对localhost的处理则更宽松。
The Fix
解决方案
Use a valid TLD so the redirect URI passes provider validation:
bash
sudo portless proxy start --https -p 443 --tld dev
portless myapp next dev使用有效的顶级域名,让重定向URI通过提供商的验证:
bash
sudo portless proxy start --https -p 443 --tld dev
portless myapp next dev
Any TLD in the Public Suffix List works: `.dev`, `.app`, `.com`, `.io`, etc.
任何在公共后缀列表中的TLD都可以使用:`.dev`、`.app`、`.com`、`.io`等。Use a domain you own
使用你拥有的域名
Bare TLDs like mean could collide with a real domain. Use a subdomain of a domain you control:
.devmyapp.devbash
sudo portless proxy start --https -p 443 --tld dev
portless myapp.local.yourcompany next dev像这样的裸顶级域名可能会导致与真实域名冲突。建议使用你控制的域名的子域名:
.devmyapp.devbash
sudo portless proxy start --https -p 443 --tld dev
portless myapp.local.yourcompany next dev
This ensures no outbound traffic reaches something you don't own. For teams, set a wildcard DNS record (`*.local.yourcompany.dev -> 127.0.0.1`) so every developer gets resolution without `/etc/hosts`.
这样可以确保不会有外部流量指向非你所有的资源。对于团队来说,设置通配符DNS记录(`*.local.yourcompany.dev -> 127.0.0.1`),这样每个开发者无需修改`/etc/hosts`就能解析域名。Provider Setup
提供商配置
- Go to Google Cloud Console > Credentials
- Create or edit an OAuth 2.0 Client ID (Web application)
- Add the portless domain to Authorized JavaScript origins:
https://myapp.dev - Add the callback to Authorized redirect URIs:
https://myapp.dev/api/auth/callback/google
Google validates domains against the Public Suffix List. The domain must end with a recognized TLD. subdomains fail this check; , , , etc. all pass.
.localhost.dev.app.comHTTPS is required for and (HSTS-preloaded). Portless handles this automatically with .
.dev.app--https- 访问Google Cloud Console > 凭据
- 创建或编辑OAuth 2.0客户端ID(Web应用类型)
- 将Portless域名添加到已授权的JavaScript来源:
https://myapp.dev - 将回调地址添加到已授权的重定向URI:
https://myapp.dev/api/auth/callback/google
Google会根据公共后缀列表验证域名,域名必须以已识别的TLD结尾。子域名无法通过此检查,而、、等均可通过。
.localhost.dev.app.com.dev.app--httpsApple
Apple
Apple Sign In does not allow or IP addresses at all.
localhost- Go to Apple Developer > Certificates, Identifiers & Profiles
- Register a Services ID
- Configure Sign In with Apple, adding the portless domain as a Return URL:
https://myapp.dev/api/auth/callback/apple
The domain must be a real, publicly-resolvable domain name. Since portless maps the domain to 127.0.0.1 locally, the browser resolves it but Apple's server-side validation may require the domain to resolve publicly too. If Apple rejects the domain, add a public DNS A record pointing to 127.0.0.1 for your dev subdomain.
Apple登录完全不允许使用或IP地址。
localhost- 访问Apple开发者中心 > 证书、标识符和配置文件
- 注册一个服务ID
- 配置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)
Microsoft (Entra / Azure AD)
- Go to Azure Portal > App registrations
- Create or edit an app registration
- Under Authentication, add a Web redirect URI:
https://myapp.dev/api/auth/callback/azure-ad
Microsoft allows with any port for development. It also accepts subdomains in most cases. Using a custom TLD with portless is still recommended for consistency across providers.
http://localhost.localhost- 访问Azure门户 > 应用注册
- 创建或编辑应用注册
- 在身份验证下,添加一个Web重定向URI:
https://myapp.dev/api/auth/callback/azure-ad
Microsoft允许在开发环境中使用带任意端口的,大多数情况下也接受子域名。但为了在各提供商间保持配置一致,仍建议使用Portless的自定义TLD。
http://localhost.localhostFacebook (Meta)
Facebook (Meta)
- Go to Meta for Developers > App Dashboard
- Under Facebook Login > Settings, add the portless URL to Valid OAuth Redirect URIs:
https://myapp.dev/api/auth/callback/facebook
Facebook requires each redirect URI to be registered exactly (no wildcards). Strict Mode (enabled by default) enforces exact matching.
- 访问Meta开发者平台 > 应用仪表板
- 在Facebook登录 > 设置下,将Portless URL添加到有效的OAuth重定向URI:
https://myapp.dev/api/auth/callback/facebook
Facebook要求每个重定向URI都必须精确注册(不支持通配符)。默认启用的严格模式会强制精确匹配。
GitHub
GitHub
- Go to GitHub Developer Settings > OAuth Apps
- Set Authorization callback URL:
https://myapp.dev/api/auth/callback/github
GitHub is permissive with localhost and subdomains. A custom TLD is not strictly required but keeps the setup consistent.
- 访问GitHub开发者设置 > OAuth应用
- 设置授权回调URL:
https://myapp.dev/api/auth/callback/github
GitHub对localhost和子域名的限制较为宽松,虽然不是必须使用自定义TLD,但使用它可以保持配置的一致性。
Auth Library Configuration
认证库配置
NextAuth / Auth.js
NextAuth / Auth.js
Set to match the portless domain:
NEXTAUTH_URLenv
NEXTAUTH_URL=https://myapp.devNextAuth uses this to construct callback URLs. Without it, callbacks may use and cause a mismatch.
localhost将设置为Portless域名:
NEXTAUTH_URLenv
NEXTAUTH_URL=https://myapp.devNextAuth会使用该值构建回调URL,如果不设置,回调可能会使用导致不匹配。
localhostPassport.js
Passport.js
Set the in each strategy to use the portless domain:
callbackURLjs
new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.BASE_URL + "/auth/google/callback",
});Set in your environment.
BASE_URL=https://myapp.dev在每个策略中设置以使用Portless域名:
callbackURLjs
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.devGeneric / Manual
通用/手动配置
Read the environment variable that portless injects into the child process:
PORTLESS_URLjs
const baseUrl = process.env.PORTLESS_URL || "http://localhost:3000";
const callbackUrl = `${baseUrl}/auth/callback`;读取Portless注入到子进程中的环境变量:
PORTLESS_URLjs
const baseUrl = process.env.PORTLESS_URL || "http://localhost:3000";
const callbackUrl = `${baseUrl}/auth/callback`;Troubleshooting
故障排除
"redirect_uri_mismatch" or "invalid redirect URI"
"redirect_uri_mismatch"或"invalid redirect URI"错误
The redirect URI sent during the OAuth flow doesn't match what's registered with the provider. Check:
- The provider's registered redirect URI matches the portless domain exactly (protocol, host, path)
- or equivalent is set to the portless URL (not
NEXTAUTH_URL)localhost - The proxy is running with the correct TLD (to verify)
portless list
OAuth流程中发送的重定向URI与提供商注册的不匹配。请检查:
- 提供商注册的重定向URI与Portless域名完全匹配(协议、主机、路径)
- 或等效变量已设置为Portless URL(而非
NEXTAUTH_URL)localhost - 代理正在使用正确的TLD运行(可通过验证)
portless list
Provider requires HTTPS
提供商要求使用HTTPS
.dev.app--httpsbash
sudo portless proxy start --https -p 443 --tld devPort 443 avoids needing a port number in URLs. Run to add the local CA to your system trust store and eliminate browser warnings.
sudo portless trust.dev.app--httpsbash
sudo portless proxy start --https -p 443 --tld dev使用443端口可以避免URL中出现端口号。运行将本地CA添加到系统信任存储中,消除浏览器警告。
sudo portless trustApple rejects the domain
Apple拒绝域名
Apple may require the domain to resolve publicly. Add a DNS A record for your dev subdomain pointing to :
127.0.0.1myapp.local.yourcompany.dev A 127.0.0.1Or use a wildcard: .
*.local.yourcompany.dev A 127.0.0.1Apple可能要求域名可公开解析。为你的开发子域名添加指向的DNS A记录:
127.0.0.1myapp.local.yourcompany.dev A 127.0.0.1或使用通配符:。
*.local.yourcompany.dev A 127.0.0.1Callback goes to wrong URL after sign-in
登录后回调到错误URL
The auth library is constructing the callback URL from instead of the portless domain. Set the appropriate environment variable:
localhost- NextAuth:
NEXTAUTH_URL=https://myapp.dev - Auth.js v5:
AUTH_URL=https://myapp.dev - Manual: is injected automatically; use it as the base URL
PORTLESS_URL
认证库正在从而非Portless域名构建回调URL。设置相应的环境变量:
localhost- NextAuth:
NEXTAUTH_URL=https://myapp.dev - Auth.js v5:
AUTH_URL=https://myapp.dev - 手动配置:会自动注入,将其用作基础URL
PORTLESS_URL
Example
示例
See for a complete working example with Next.js + NextAuth + Google OAuth using .
examples/google-oauth--tld dev查看获取完整的工作示例,包含Next.js + NextAuth + Google OAuth,并使用参数。
examples/google-oauth--tld dev