ory kratos 与 go-kratos/kratos 无关,是独立 http 服务;微服务应通过其公开 api(如 /sessions/whoami)验证身份和 mfa 状态,而非自行解析 jwt 或集成 sdk。

直接上结论:Ory Kratos 不是 Kratos 微服务框架的组件,它和 go-kratos/kratos 完全无关——两者同名纯属巧合。想在 Golang 微服务中用好 Ory Kratos 做 MFA 认证,关键不是“集成框架”,而是厘清边界、定义职责、正确对接。
别把 Ory Kratos 当成中间件来 import
Ory Kratos 是一个独立运行的 HTTP 服务(Go 编写),不是 Go 模块。你不能 import "github.com/ory/kratos" 然后在自己的微服务里调用它的登录逻辑——它不提供 SDK 风格的 Go 客户端封装(官方只维护 ory/sdk 的 REST 客户端,且推荐用 HTTP 调用)。
- 错误做法:在业务服务里直接初始化
KratosClient并复用其 session 或 identity 结构体——这会绕过 Kratos 的策略引擎、钩子(hooks)、审计日志和 MFA 状态机 - 正确姿势:所有认证相关动作(登录、MFA 挑战、恢复、验证)必须走 Kratos 的公开 API,比如
/self-service/login/api、/self-service/flows/requests/login - 你的 Golang 微服务只做两件事:1)重定向用户到 Kratos 的 UI 流程页(如
/login);2)用 JWT 或 session cookie 向 Kratos 的/sessions/whoami验证当前请求身份
JWT 验证必须用 Kratos 的 public API,别自己解析
Kratos 默认签发的 session token 是 opaque token(非 JWT),但你可以配置它输出 JWT(需启用 identity.traits 映射和 session.cookie.same_site 兼容设置)。即便如此,也不建议你的微服务自己 jwt.Parse 验证——Kratos 的 /sessions/whoami 接口才是唯一可信的身份断言源。
- 原因:Kratos 会在该 endpoint 实时校验 session 状态、MFA 完成度、账户锁定、异地登录风险等动态策略,而静态 JWT 解析无法感知这些
- 典型流程:前端带
Authorization: Bearer <token></token>→ 你的服务向 KratosGET /sessions/whoami转发请求 → 校验响应中的authenticated_at、authentication_methods字段判断是否满足 MFA 要求 - 注意响应头
X-Session-Expires-In,它告诉你 session 还剩多久过期,比 JWT 的exp更准
多通道 MFA(SMS/Email/TOTP/Passkey)要靠 Kratos 的自定义 flow 和 courier 配置
Kratos 内置支持 TOTP 和 WebAuthn(Passkey),但 SMS 和 Email 发送依赖 courier 模块——它不自带发送能力,必须对接外部服务(如 Twilio、SendGrid、SMTP)。
- 常见坑:只配了
courier.smtp.host却没设courier.smtp.username,导致邮件静默失败,用户收不到验证码,日志里只有courier: failed to send message无细节 - 多通道选择逻辑不在代码里,而在 Kratos 的身份 schema(
identity.schema.json)和自定义 hook 中:比如用户注册时填了手机号就自动启用 SMS MFA,填了邮箱则 fallback 到 Email - TOTP 密钥生成必须用 Kratos 的
/self-service/registration/api流程返回的totp.secret,别自己用crypto/rand生成——否则和 Kratos 内部验证逻辑不一致
与 go-kratos/kratos 框架共存时,鉴权中间件只负责“转发+透传”,不负责“决策”
如果你的微服务基于 go-kratos/kratos 构建,它的 jwt.Server 中间件可以保留,但作用仅限于:提取并透传 token,再调用 Kratos API 做最终校验。不要让它承担 MFA 级别的权限判断。
- 示例错误配置:
jwt.WithClaims(&CustomClaims{})里硬编码"mfa_required": true—— 这个字段应由 Kratos 的/sessions/whoami响应动态决定 - 正确链路:
go-kratos/kratos的 HTTP 中间件 → 提取Authorizationheader → 调用 Kratos/sessions/whoami→ 检查响应 body 中authentication_methods是否包含{"type":"totp","completed":true}或{"type":"webauthn","completed":true} - 特别注意:Kratos 的 MFA 完成状态是 session 粒度的,不是 token 粒度。一次登录可能经历多个 MFA 步骤,
/sessions/whoami才是唯一真相源
最易被忽略的一点:Kratos 的 MFA 并非“开启即生效”,它依赖用户实际完成流程。很多团队部署完就以为万事大吉,结果发现用户从未触发过 TOTP 绑定,或者 Passkey 注册被浏览器拦截——必须通过 /self-service/flows/settings 主动引导用户完成 MFA 初始化,且这个流程本身也要受 Kratos 的 session 策略保护。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











