oauth

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OAuth with Portless

结合Portless使用OAuth

OAuth providers validate redirect URIs against domain rules.
.localhost
subdomains fail on most providers because they are not in the Public Suffix List or are explicitly blocked. Portless fixes this with
--tld
to serve apps on real, valid domains.
OAuth提供商会根据域名规则验证重定向URI。
.localhost
子域名在大多数提供商处无法通过验证,因为它们不在公共后缀列表(Public Suffix List,PSL)中,或是被明确阻止。Portless通过
--tld
参数解决此问题,让应用在真实有效的域名上运行。

The Problem

问题描述

When portless uses the default
.localhost
TLD, OAuth providers reject redirect URIs like
http://myapp.localhost:1355/callback
:
Provider
localhost
.localhost
subdomains
Reason
GoogleAllowedRejectedNot in their bundled PSL
AppleRejectedRejectedNo localhost at all
MicrosoftAllowedAllowedPermissive localhost handling
FacebookAllowedVariesMust register each URI exactly
GitHubAllowedAllowedPermissive
Google and Apple are the strictest. Microsoft and GitHub are more lenient with localhost.
当Portless使用默认的
.localhost
顶级域名(TLD)时,OAuth提供商会拒绝类似
http://myapp.localhost:1355/callback
这样的重定向URI:
提供商
localhost
.localhost
子域名
原因说明
Google允许拒绝不在其内置的PSL列表中
Apple拒绝拒绝完全不支持localhost
Microsoft允许允许对localhost处理较为宽松
Facebook允许情况不一必须精确注册每个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
.dev
mean
myapp.dev
could collide with a real domain. Use a subdomain of a domain you control:
bash
sudo portless proxy start --https -p 443 --tld dev
portless myapp.local.yourcompany next dev
.dev
这样的裸顶级域名可能会导致
myapp.dev
与真实域名冲突。建议使用你控制的域名的子域名:
bash
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

提供商配置

Google

Google

  1. Go to Google Cloud Console > Credentials
  2. Create or edit an OAuth 2.0 Client ID (Web application)
  3. Add the portless domain to Authorized JavaScript origins:
    https://myapp.dev
  4. 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.
.localhost
subdomains fail this check;
.dev
,
.app
,
.com
, etc. all pass.
HTTPS is required for
.dev
and
.app
(HSTS-preloaded). Portless handles this automatically with
--https
.
  1. 访问Google Cloud Console > 凭据
  2. 创建或编辑OAuth 2.0客户端ID(Web应用类型)
  3. 将Portless域名添加到已授权的JavaScript来源
    https://myapp.dev
  4. 将回调地址添加到已授权的重定向URI
    https://myapp.dev/api/auth/callback/google
Google会根据公共后缀列表验证域名,域名必须以已识别的TLD结尾。
.localhost
子域名无法通过此检查,而
.dev
.app
.com
等均可通过。
.dev
.app
域名要求使用HTTPS(已预加载HSTS),Portless通过
--https
参数自动处理此需求。

Apple

Apple

Apple Sign In does not allow
localhost
or IP addresses at all.
  1. Go to Apple Developer > Certificates, Identifiers & Profiles
  2. Register a Services ID
  3. 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登录完全不允许使用
localhost
或IP地址。
  1. 访问Apple开发者中心 > 证书、标识符和配置文件
  2. 注册一个服务ID
  3. 配置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)

  1. Go to Azure Portal > App registrations
  2. Create or edit an app registration
  3. Under Authentication, add a Web redirect URI:
    https://myapp.dev/api/auth/callback/azure-ad
Microsoft allows
http://localhost
with any port for development. It also accepts
.localhost
subdomains in most cases. Using a custom TLD with portless is still recommended for consistency across providers.
  1. 访问Azure门户 > 应用注册
  2. 创建或编辑应用注册
  3. 身份验证下,添加一个Web重定向URI:
    https://myapp.dev/api/auth/callback/azure-ad
Microsoft允许在开发环境中使用带任意端口的
http://localhost
,大多数情况下也接受
.localhost
子域名。但为了在各提供商间保持配置一致,仍建议使用Portless的自定义TLD。

Facebook (Meta)

Facebook (Meta)

  1. Go to Meta for Developers > App Dashboard
  2. 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.
  1. 访问Meta开发者平台 > 应用仪表板
  2. Facebook登录 > 设置下,将Portless URL添加到有效的OAuth重定向URI
    https://myapp.dev/api/auth/callback/facebook
Facebook要求每个重定向URI都必须精确注册(不支持通配符)。默认启用的严格模式会强制精确匹配。

GitHub

GitHub

  1. Go to GitHub Developer Settings > OAuth Apps
  2. 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.
  1. 访问GitHub开发者设置 > OAuth应用
  2. 设置授权回调URL
    https://myapp.dev/api/auth/callback/github
GitHub对localhost和子域名的限制较为宽松,虽然不是必须使用自定义TLD,但使用它可以保持配置的一致性。

Auth Library Configuration

认证库配置

NextAuth / Auth.js

NextAuth / Auth.js

Set
NEXTAUTH_URL
to match the portless domain:
env
NEXTAUTH_URL=https://myapp.dev
NextAuth uses this to construct callback URLs. Without it, callbacks may use
localhost
and cause a mismatch.
NEXTAUTH_URL
设置为Portless域名:
env
NEXTAUTH_URL=https://myapp.dev
NextAuth会使用该值构建回调URL,如果不设置,回调可能会使用
localhost
导致不匹配。

Passport.js

Passport.js

Set the
callbackURL
in each strategy to use the portless domain:
js
new GoogleStrategy({
  clientID: process.env.GOOGLE_CLIENT_ID,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET,
  callbackURL: process.env.BASE_URL + "/auth/google/callback",
});
Set
BASE_URL=https://myapp.dev
in your environment.
在每个策略中设置
callbackURL
以使用Portless域名:
js
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

Generic / Manual

通用/手动配置

Read the
PORTLESS_URL
environment variable that portless injects into the child process:
js
const baseUrl = process.env.PORTLESS_URL || "http://localhost:3000";
const callbackUrl = `${baseUrl}/auth/callback`;
读取Portless注入到子进程中的
PORTLESS_URL
环境变量:
js
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:
  1. The provider's registered redirect URI matches the portless domain exactly (protocol, host, path)
  2. NEXTAUTH_URL
    or equivalent is set to the portless URL (not
    localhost
    )
  3. The proxy is running with the correct TLD (
    portless list
    to verify)
OAuth流程中发送的重定向URI与提供商注册的不匹配。请检查:
  1. 提供商注册的重定向URI与Portless域名完全匹配(协议、主机、路径)
  2. NEXTAUTH_URL
    或等效变量已设置为Portless URL(而非
    localhost
  3. 代理正在使用正确的TLD运行(可通过
    portless list
    验证)

Provider requires HTTPS

提供商要求使用HTTPS

.dev
and
.app
TLDs are HSTS-preloaded -- browsers force HTTPS. Start the proxy with
--https
:
bash
sudo portless proxy start --https -p 443 --tld dev
Port 443 avoids needing a port number in URLs. Run
sudo portless trust
to add the local CA to your system trust store and eliminate browser warnings.
.dev
.app
TLD已预加载HSTS——浏览器会强制使用HTTPS。启动代理时添加
--https
参数:
bash
sudo portless proxy start --https -p 443 --tld dev
使用443端口可以避免URL中出现端口号。运行
sudo portless trust
将本地CA添加到系统信任存储中,消除浏览器警告。

Apple 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.1
:
myapp.local.yourcompany.dev  A  127.0.0.1
Or use a wildcard:
*.local.yourcompany.dev  A  127.0.0.1
.
Apple可能要求域名可公开解析。为你的开发子域名添加指向
127.0.0.1
的DNS A记录:
myapp.local.yourcompany.dev  A  127.0.0.1
或使用通配符:
*.local.yourcompany.dev  A  127.0.0.1

Callback goes to wrong URL after sign-in

登录后回调到错误URL

The auth library is constructing the callback URL from
localhost
instead of the portless domain. Set the appropriate environment variable:
  • NextAuth:
    NEXTAUTH_URL=https://myapp.dev
  • Auth.js v5:
    AUTH_URL=https://myapp.dev
  • Manual:
    PORTLESS_URL
    is injected automatically; use it as the base URL
认证库正在从
localhost
而非Portless域名构建回调URL。设置相应的环境变量:
  • NextAuth
    NEXTAUTH_URL=https://myapp.dev
  • Auth.js v5
    AUTH_URL=https://myapp.dev
  • 手动配置
    PORTLESS_URL
    会自动注入,将其用作基础URL

Example

示例

See
examples/google-oauth
for a complete working example with Next.js + NextAuth + Google OAuth using
--tld dev
.
查看
examples/google-oauth
获取完整的工作示例,包含Next.js + NextAuth + Google OAuth,并使用
--tld dev
参数。