零流程身份:我为何用 Go 构建单二进制 OIDC Provider
Source: Dev.to
请提供您希望翻译的文章正文内容,我将为您翻译成简体中文并保留原有的格式、Markdown 语法以及技术术语。
现有解决方案的问题
身份基础设施众所周知非常复杂。一个典型的自托管部署包括:
- 数据库服务器
- 缓存层(例如 Redis)
- 工作队列
- 身份服务本身
在一台 2 GB RAM 的小型 VPS 上运行轻量级 OIDC 服务器时,我很快发现现有的生态要么在运营上让人疲惫不堪,要么在结构上不符合我的需求。
我发现的不足
| Provider | Issue |
|---|---|
| Casdoor | 演示实例每 5 分钟回收一次账户,导致无法测试账户删除。 |
| PocketId | 默认仅支持 Passkey。使用旧操作系统或受限浏览器的用户将被锁定。 |
这些障碍促使我将原本为工作中的前端库构建的 OIDC 协议服务器转换为完整的 IdP,并不断自问:这会减轻还是增加运营者的负担?
Auténtico 的设计原则
- Single binary – 整个 IdP 作为一个 Go 可执行文件运行。
- Embedded SQLite – 所有状态都保存在单个文件中;无需外部数据库服务器,避免了连接池调优、凭证轮换以及网络分区等问题。
- Zero external infrastructure – 不使用 Redis、Postgres 或消息队列。后台 goroutine 会自动清除过期的令牌、会话和授权码。
- Embedded UIs – 管理仪表盘(React/Ant Design)和面向用户的账户 UI(React/Tailwind)通过
go:embed编译进二进制文件。无需单独的前端部署。
灵活的认证模式
Auténtico 提供三种运行时可切换的认证模式(无需重启):
passwordpassword_and_passkeypasskey_only
如果使用 passkey_only 的部署遇到浏览器不兼容问题,管理员可以在管理界面即时切换设置,回退到密码。其他回退方式包括:
- TOTP(浏览器内二维码注册)
- 邮件 OTP
- 硬件支持的 FIDO2 认证(配合无缝的首次登录注册)
垂直切片架构
代码库遵循严格的垂直切片布局,每个包拥有其对应的功能切片:
pkg/login/
model.go
handler.go
service.go
// Database CRUD- 保持代码“刻意不聪明”,使 AI 助手能够轻松生成样板代码。
- 实现了快速创建 > 700 个测试,覆盖率约为 ~80 %。
性能与可扩展性
SQLite 将写入序列化,因此 Auténtico 并不适用于主动‑主动的多区域部署。尽管如此,其性能范围对于内部工具和中小型应用仍然相当宽裕。
| 并发虚拟用户 | 错误率 | 登录 p95 | 令牌 p95 | 判定 |
|---|---|---|---|---|
| 20 | 0 % | 86 ms | 54 ms | 舒适 – 几乎感受不到 |
| 100 | 0 % | 611 ms | 647 ms | 支持 – 完全可用 |
| 500 | 0 % | 3.36 s | 3.89 s | 性能下降 – 延迟明显 |
测试使用 k6 进行;SQLite 的忙等待超时会将请求排队,从而增加延迟,而不是直接抛出错误。
对于大多数团队来说,用 零运维开销 换取无限水平扩展是更合适的选择。
Feature checklist
- OIDC 发现 – 发布
/.well-known/openid-configuration。 - JWK 集合 – 在
/.well-known/jwks.json暴露公共签名密钥。 - RS256 JWT 签名 – 非对称签名;私钥永不离开 IdP。
- OAuth2/OIDC 协议实现。
- 管理 UI – 管理客户端、用户和会话。
- 账户 UI – 用户管理其个人资料。
- Swagger/OpenAPI 文档 – API 规范会自动发布。
谁应该考虑使用 Auténtico?
- 小团队或独立开发者,需要一个身份提供者但没有专职系统管理员。
- 运行内部工具、自托管环境或中小规模应用的组织,运营简便性比大规模水平扩展更重要。
GitHub: