在开发多个应用时,一个常见的痛点是 账号体系分散:每个应用都有自己的登录页面和用户表,用户体验差,开发和维护成本也高。
如果能把用户统一在一个「认证中心」里管理,所有应用共享同一个登录入口,就能实现 单点登录 (Single Sign-On, SSO) ------ 用户只需登录一次,就能访问所有应用。
本文将介绍如何基于 Supabase Auth 打造一个「统一认证中心」,并让多个应用(Web / App / 桌面端)共用同一个账号系统。
一、为什么选择 Supabase 做认证中心?
Supabase 内置了完整的 身份认证 (Auth) 模块,支持:
-
邮箱密码登录、魔法链接、手机 OTP
-
Google / GitHub / Apple 等 OAuth 登录
-
管理 JWT 会话,支持 anon 与 service_role 等权限
-
内置邮件模板、回调配置
这些能力非常适合作为一个 独立的身份服务 使用,避免重复造轮子。
二、架构思路:认证中心 + 多子应用
核心思路是:
-
用户访问某个子应用(例如「彩旗清单」)。
-
子应用检测未登录,重定向到认证中心。
-
用户在认证中心完成登录(账号密码 / 社交登录)。
-
登录成功后,认证中心带着 token 或 授权信息 回跳到子应用。
-
子应用接收并保存登录态,后续请求携带 JWT 访问 Supabase API。
用文本流程图表示如下:
用户 → 子应用 A (未登录)
→ 重定向到认证中心 (Supabase Auth 登录页)
→ 输入账号 / 社交登录
→ 验证成功 → 认证中心生成 token
→ 重定向回子应用 A callback (带 token)
→ 子应用 A 保存会话 → 登录成功
用户再访问子应用 B
→ 重定向到认证中心
→ 已有登录态 (cookie/session),无需再次输入密码
→ 回调到子应用 B → 登录成功
这样,多个子应用只要接入统一认证中心,就能实现单点登录。
三、Supabase 中的关键配置
Supabase 控制台里和回调相关的设置主要有三个:
1. Site URL
-
位置 :Auth → URL Configuration → Site URL
-
作用:当登录请求中没有指定 redirect_to 时,用户将被重定向到这个默认地址。
-
限制:只能填一个,不能使用通配符。
-
示例:
通常这里填认证中心本身的 URL,作为兜底回调。
2. Additional Redirect URLs
-
位置 :Auth → URL Configuration → Redirect URLs
-
作用:允许的回调地址白名单。只有列在这里的 URL 才能被 Supabase 用作回调地址。
-
示例:
https://app-a.mycompany.com/callback
https://app-b.mycompany.com/callback
http://localhost:5173/callback (本地开发调试)
所有子应用的回调地址都必须写在这里,否则会报错。
3. 前端调用时指定 redirectTo
在子应用里调用 Supabase SDK 发起登录请求时,可以用 options.redirectTo 指定回调地址:
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: 'https://app-a.mycompany.com/callback'
}
});
这样,用户完成登录后,Supabase 就会把他们带回 redirectTo 指定的子应用 callback 页面。
四、子应用如何处理回调?
每个子应用都需要一个 callback 页面,负责接收 Supabase 返回的 token 并保存。常见做法有:
-
在 callback 页面解析 token
-
Supabase 会在 URL 里附带 access_token、refresh_token。
-
你可以用 supabase.auth.setSession() 将其保存到本地。
-
-
存储会话
-
Web 端:localStorage / cookie
-
移动端 / 桌面端:安全存储方案(例如 iOS Keychain、Android Keystore)
-
-
后续请求携带 JWT
-
所有 API 请求通过 Supabase SDK 自动带上 access_token。
-
如果 token 过期,SDK 会自动用 refresh_token 续期。
-
五、完整示例配置清单
假设你有三个应用:认证中心 + 两个子应用:
-
子应用 A(彩旗清单):https://app-a.mycompany.com
-
子应用 B(彩旗笔记):https://app-b.mycompany.com
1️⃣ Supabase 控制台配置
Auth → URL Configuration
-
Site URL:
-
Redirect URLs:
https://app-a.mycompany.com/callback
https://app-b.mycompany.com/callback
http://localhost:5173/callback
2️⃣ 子应用跳转登录(统一入口)
子应用只需做 跳转到认证中心,不直接调用 signInWithOAuth:
子应用 A
function login() {
const authCenterUrl = "https://auth.mycompany.com/login";
const callbackUrl = encodeURIComponent("https://app-a.mycompany.com/callback");
window.location.href = `${authCenterUrl}?redirectTo=${callbackUrl}`;
}
子应用 B
function login() {
const authCenterUrl = "https://auth.mycompany.com/login";
const callbackUrl = encodeURIComponent("https://app-b.mycompany.com/callback");
window.location.href = `${authCenterUrl}?redirectTo=${callbackUrl}`;
}
这样所有子应用 共享同一认证中心,用户只需登录一次。
3️⃣ 认证中心登录页面
认证中心负责调用 Supabase OAuth:
// 获取子应用回调地址
const params = new URLSearchParams(window.location.search);
const redirectTo = params.get('redirectTo') || 'https://auth.mycompany.com';
// 调用 Supabase OAuth
supabase.auth.signInWithOAuth({
provider: 'google',
options: { redirectTo }
});
-
用户登录成功后,会被 跳转回对应子应用的回调页面。
-
子应用在回调页面解析 token 并设置 session。
4️⃣ 回调页面(子应用)
子应用的 /callback 页面负责:
const hash = new URLSearchParams(window.location.hash.slice(1));
const accessToken = hash.get('access_token');
if (accessToken) {
supabase.auth.setSession({ access_token: accessToken }).then(() => {
window.location.href = '/'; // 登录完成,跳回首页
});
}
这样可以确保
-
登录入口统一在认证中心,子应用不重复实现 OAuth。
-
登录成功后回到正确子应用。
-
多个子应用共享同一账号体系,用户只需登录一次。
六、总结
通过合理配置 Site URL、Redirect URLs 和 redirectTo 参数,我们可以用 Supabase 轻松搭建一个统一认证中心,并让多个子应用共用同一个账号系统。
好处是:
-
用户体验更好:一次登录,多处通行。
-
开发成本更低:登录逻辑集中在认证中心,子应用只需要处理 token。
-
安全性更高:回调地址白名单防止 token 泄露。
这就是用 Supabase 实现 单点登录(SSO) 的完整方案。