你以为认证只是“发个 JWT”,直到客户要 SSO、组织隔离、角色权限、邀请成员、CLI 登录、MCP 授权,你才发现自己正在手搓半个 Auth0。
很多程序员创业做 SaaS,前几天都很乐观。
第一天:
POST /login
→ 校验密码
→ 签发 JWT
→ 前端存 token
→ 完事
第二周:
加一个 Google 登录吧。
第一个客户来了:
能不能支持邀请同事?
第二个客户来了:
我们公司有多个部门,不同部门权限不一样。
第三个客户来了:
我们用 Azure AD,能接企业 SSO 吗?
然后 AI Agent 来了:
这个 Agent 能不能代表用户调用工具?
这个 MCP Server 到底该拿谁的权限?
CLI 登录怎么办?
机器之间调用又怎么办?
到这一步你才发现:
登录,从来不是一个页面。
JWT,也从来不是权限系统。
认证真正难的地方,是“谁在什么上下文里,可以访问什么”。
最近读了 Logto 的源码,我最大的感受是:
它不是想帮你做一个更好看的登录页。
它想把 SaaS 最容易失控的一整套身份、组织、权限、协议和登录体验,收拢成一层基础设施。
Logto 官方将自己定位为面向 SaaS 和 AI 应用的开源身份认证与授权基础设施,覆盖 OIDC、OAuth 2.1、多租户、企业 SSO、RBAC、组织能力及 MCP / Agent 场景。(GitHub)
但如果只把它理解成“开源 Auth0”或者“Supabase Auth 替代品”,其实低估它了。
它真正想解决的,是一个更现实的问题:
当你的产品从“一个 App”
变成“多个应用 + 多个客户 + 多种登录方式 + 多层权限 + 多个 Agent”
身份系统还能不能不崩?
一、程序员最容易低估的坑:认证不是 Login,权限才是无底洞
很多项目一开始的权限模型,都长这样:
user.role === 'admin'
或者:
if (token.role === 'editor') {
allow();
}
早期完全没问题。
但当产品开始卖给企业客户后,问题会突然爆发。
一个用户可能同时属于多个公司。
同一个用户在 A 公司是管理员,在 B 公司只是普通成员。
同一个用户能管理项目 X,却不能看项目 Y。
同一个企业可能有自己的 SSO、自己的域名、自己的管理员、自己的成员邀请流程。
于是你原来的权限判断开始变成:
if (
user.role === 'admin' &&
user.organizationId === currentOrganizationId &&
project.organizationId === currentOrganizationId &&
user.permissions.includes('project:write')
) {
allow();
}
再过几个月,代码库里会出现几十处这样的判断。
没人知道哪一处漏了组织隔离。
没人知道某个 API 是否真的校验了 scope。
更没人敢轻易改 JWT 结构。
这就是为什么很多 SaaS 最后不是死在业务逻辑,而是死在“权限债务”。
Logto 的源码里,组织、组织邀请、组织角色、组织 scope、应用、用户、SSO、登录体验、验证流程等能力,并不是散落在几个可选插件里,而是直接被拆进核心路由和数据模型边界中。(GitHub)
这意味着它的思路不是:
先做登录,
以后再补权限。
而是:
身份
→ 应用
→ 组织
→ 资源
→ Scope
→ 角色
→ Token Claim
→ API 访问
从一开始就必须是一条链。
二、Logto 最像“基础设施”的地方:它不是一个认证服务,而是一套 Tenant Runtime
读源码时,最值得注意的不是登录界面。
而是它处理请求的方式。
Logto 的核心服务是一个 Koa 应用,但请求进来后,不会直接进入固定的认证逻辑。
它会先根据 URL、域名或自定义域名,识别请求属于哪个 Tenant;再从 Tenant Pool 中拿到对应的运行时实例,交给该 Tenant 自己的 Koa App、OIDC Provider、数据库连接、配置、Connector 和业务库去处理。(GitHub)
简单理解:
请求进入 Logto
↓
识别当前租户
↓
加载该租户的配置、Issuer、数据库连接
↓
加载该租户的登录方式、连接器、SSO 配置
↓
进入该租户自己的认证运行时
这不是一个普通的“多租户字段隔离”。
它更像:
Tenant = 一套独立身份运行环境
源码里甚至专门处理了一个很细的细节:
如果用户通过租户的自定义域名访问,OIDC 的 issuer 也要基于这个自定义域名构建。
这看起来只是 URL 问题。
实际上却是身份系统里非常要命的问题。
因为 OIDC 世界中,issuer、redirect URI、cookie、JWKS、token audience、客户端配置,全都不能乱。
你不能让:
customer-a.example.com
最后签发一个:
issuer = auth.yourcompany.com
却又让客户以为这是自己的企业认证入口。
Logto 在请求层先识别 Tenant,再根据是否为自定义域名构建不同 endpoint 的设计,本质是在处理“身份边界”和“品牌边界”同时存在的复杂场景。(GitHub)
这才是很多团队手写认证系统时,最容易后知后觉的坑。
三、真正难的不是 JWT,而是 OIDC 生命周期
很多人对认证系统的理解,还停留在:
账号密码正确
→ 返回 token
但真实世界里,一次认证至少可能涉及:
登录
注册
社交登录
短信验证
邮件验证
MFA
设备授权
刷新 Token
Token 吊销
退出登录
第三方应用授权
用户同意 Scope
企业 SSO
机器对机器调用
账号关联
风险验证
这不是一个 API。
这是一整套协议状态机。
Logto 没有试图从零造一个 OAuth Server,而是基于 oidc-provider 构建 OIDC 核心,再把自己的租户、组织、资源、用户、Token Claim、审计、Connector 和应用策略塞进这条协议链。源码中启用了 UserInfo、Token Revocation、Introspection、Client Credentials、Backchannel Logout、Device Flow、RP-Initiated Logout、Resource Indicators 等能力。(GitHub)
你可以把它理解成:
OIDC Provider
+
PostgreSQL 状态存储
+
多租户运行时
+
组织授权模型
+
用户登录体验
+
企业级连接器
这才是 Logto 的底座。
而不是一个:
login()
函数。
四、它最关键的一层:把 OIDC 的“协议能力”,翻译成 SaaS 的“业务权限”
OIDC 很强。
但它天然不懂你的 SaaS 业务。
OIDC 不知道:
谁是某个组织的管理员;
谁能邀请成员;
谁能导出财务报表;
谁能调用某个 AI Agent;
谁能访问某个 MCP 工具;
谁只能读,谁可以写;
谁的权限仅限某一个组织。
这些事情,不能只靠一个 sub。
所以 Logto 的实现里,有一层非常关键的东西:
Application
Resource
Scope
Organization
Role
Claim
比如第三方应用申请权限时,不是“给了 token 就能干所有事”。
源码里会先查询该应用允许的用户 scope,并限制第三方客户端可请求的 scope;资源 scope 和组织 scope 则会继续在资源服务信息处理过程中筛选。(GitHub)
换句话说,它不是:
拿到 Access Token
→ 默认拥有一切权限
而是:
用户身份
+ 当前应用
+ 当前组织
+ 当前资源
+ 当前 Scope
+ 当前客户端配置
→ 最终得到什么 Token
→ Token 能访问什么 API
这才是 SaaS 权限设计最该有的样子。
不是问:
这个用户是不是管理员?
而是问:
这个用户,代表哪个组织,通过哪个应用,试图访问哪个资源,用什么 scope 做什么动作?
这两个问题,差了一个企业级权限系统。
五、为什么很多“登录 SDK”最后都会烂掉?因为它们没有管理身份状态
很多人以为认证服务的状态很简单:
User
Session
Token
实际上,认证系统会产生大量短生命周期状态。
比如:
authorization code
interaction session
consent
device code
refresh token
grant
access token
logout session
verification state
这些状态不是简单放 Redis 就完事。
它们要考虑:
什么时候失效;
什么时候消费;
什么时候撤销;
什么时候关联用户;
什么时候关联组织;
什么时候被刷新;
什么时候被强制吊销;
什么时候能被审计。
Logto 的 OIDC Adapter 把 oidc-provider 的模型状态写入自己的持久化层,包含按 ID、UID、User Code 查找,消费实例、销毁实例、按 Grant 撤销、更新过期时间等操作。(GitHub)
程序员看到这里应该会意识到:
Logto 做的不是“Token 生成器”。
它是在维护一套身份状态机。
而身份状态机,才是认证系统真正容易翻车的地方。
你可以自己发 JWT。
但你很难优雅解决:
用户换手机了,如何让旧设备退出?
员工离职后,如何撤销所有会话?
企业管理员关闭某个成员权限后,旧 Token 怎么办?
用户切换组织后,Token 里的权限还算不算数?
第三方应用取消授权后,Refresh Token 怎么处理?
这些问题,最后都会从产品需求,变成安全事故。
六、Logto 最不“性感”、却最值钱的设计:Connector 不是功能,是扩展体系
很多身份产品支持 Google 登录。
再好一点,支持 GitHub、Apple、Microsoft。
但 Logto 的 Connector 目录里,不只是社交登录,还包括邮箱、短信、企业身份、云通信、国内生态和多种第三方服务。
例如代码库中可以看到 Google、GitHub、GitLab、Apple、Azure AD、Discord、飞书、钉钉、支付宝、阿里云邮件、阿里云短信、AWS SES、Mailgun 等 Connector。(GitHub)
这说明它不是单纯在堆“登录按钮”。
它在做一个 Connector Framework。
你可以把它理解成:
Logto 核心负责:
协议、用户、组织、权限、Token、流程。
Connector 负责:
Google 怎么登录;
飞书怎么登录;
短信怎么发;
邮件怎么发;
企业 IdP 怎么接;
某个国家或地区的身份渠道怎么接。
这套拆法非常工程化。
因为认证系统最容易变成一锅粥的地方,就是把所有第三方身份提供商、短信服务商、邮件服务商、企业 IdP 的差异,全塞进核心逻辑。
最后一改 Google 登录,短信验证码坏了。
一接企业 SSO,邮箱注册流程又崩了。
Logto 把这些渠道拆到 Connector 层,本质是在保护认证核心不被第三方生态绑架。
七、登录体验为什么也必须是基础设施,而不是“前端顺手写一下”?
很多工程师会说:
协议我懂,后端我会写,登录页面我让前端做一下不就行了?
问题是,登录体验不是一个页面。
它是一整套“身份交互状态”。
比如:
输入邮箱后,是登录还是注册?
账号不存在时要不要自动创建?
用户先绑手机号还是邮箱?
企业 SSO 放在第几步?
验证码失败后怎么重试?
MFA 在什么节点触发?
用户同意授权页面怎么展示?
用户退出时怎么清理会话?
这些不是 UI 细节。
这些都会影响协议状态、用户状态、账户安全和转化率。
Logto 的代码库里将面向终端用户的注册和登录体验单独拆成 experience 包,而核心 Tenant Runtime 则负责挂载 Experience、Account Center、Consent、Session Guard、SSR 和安全头。(GitHub)
这个设计背后的判断很重要:
登录页不是业务页面。
登录页是身份系统的一部分。
一旦你把它当成普通页面,后面接 MFA、SSO、Consent、账号绑定、设备登录、密码策略时,就会开始痛苦。
八、AI Agent 出现后,认证系统又被重新洗牌了
过去,认证系统的主角是:
人
→ 浏览器
→ Web App
→ API
现在变成了:
人
→ AI Agent
→ MCP Server
→ 外部工具
→ 第三方 API
→ 企业资源
问题一下子复杂了。
一个 Agent 到底拿谁的身份?
拿用户身份?
拿系统身份?
拿组织身份?
拿临时委托权限?
拿机器账号?
拿某个 Tool 的独立 Scope?
如果没有一套清晰的授权模型,AI Agent 很容易变成:
一个权限极大的机器人,
拿着用户 Token 到处调用工具。
这非常危险。
Logto 在 README 里明确把 MCP 和 Agent-based architectures 放在支持范围内;源码里也同时具备 Device Flow、Client Credentials、Resource Indicators、第三方客户端 scope 限制、Token Claim 扩展等能力。(GitHub)
我的判断是:
Logto 想做的不只是“用户登录”。
它也在为未来的 Agent 授权模型铺路。
未来一个成熟的 Agent 系统,至少应该能回答:
这个 Agent 代表谁?
它属于哪个组织?
它能访问什么资源?
它调用某个 MCP Tool 时,获得的是长期权限还是短期授权?
用户撤销权限后,Agent 还能不能继续跑?
这些问题,最终都不是 Prompt 能解决的。
它们只能靠身份系统解决。
九、但别误会:上了 Logto,不等于你不用设计权限
这也是最需要提醒程序员的一点。
Logto 可以解决很多基础问题:
认证协议;
Token 生命周期;
用户目录;
社交登录;
企业 SSO;
组织;
RBAC;
资源 Scope;
连接器;
登录体验;
多租户基础设施。
但它不会自动替你定义:
什么角色应该拥有退款权限;
什么人可以删除项目;
某个 AI Agent 是否可以代表用户发邮件;
不同套餐客户看到哪些功能;
你的业务数据如何按组织隔离;
某个“管理员”是否可以越权访问其他企业数据。
这些仍然是你的产品和业务逻辑。
最危险的做法是:
有了 RBAC
→ 就以为权限问题解决了。
真正成熟的做法是:
Logto 管身份与授权基础设施;
你的业务系统管理领域权限与数据边界;
两者通过 Scope、Claim、Organization Context 对齐。
这才是可维护的分工。
最后:真正值钱的认证系统,不是“让用户登录”,而是“让系统敢于授权”
过去,登录功能只是产品边角料。
现在,身份系统已经变成 SaaS 的核心基础设施。
因为你的产品越复杂,身份关系就越复杂:
用户越来越多;
组织越来越多;
应用越来越多;
权限越来越细;
企业客户越来越多;
AI Agent 越来越多;
外部工具越来越多。
到最后,最难的问题不再是:
用户能不能登录?
而是:
系统凭什么相信他?
他代表谁?
他在哪个组织里?
他能访问什么?
他的权限什么时候应该失效?
他让 Agent 做事时,Agent 又该拿什么权限?
Logto 的价值,不在于它能帮你少写一个登录页面。
而在于它试图把这些原本会散落在前端、后端、JWT、中间件、数据库和第三方 SDK 里的复杂度,重新收拢成一套身份基础设施。
真正厉害的 SaaS,不是用户登录后就放行。
而是它知道:
谁来了,
为什么能进来,
进来后能做什么,
以及什么时候必须让他离开。
![图片[1]-最难的不是发 JWT,而是控制谁能做什么-新觅源码库](https://bt-1408553325.cos.ap-guangzhou.myqcloud.com/wp-content/uploads/2026/07/image-1-1024x536.png)
















暂无评论内容