登录与 Session
@downcity/services 里的统一登录入口、OAuth callback、session、me 和 logout 在产品链路里的位置。
accounts service 承载账号表、better-auth runtime、OAuth callback、会话、profile 和 City user_token 签发。具体登录方式由 provider 决定。
登录入口怎么理解
产品侧登录是一个统一状态机:
providerslogin/startlogin/continuelogin/result
常见产品接法里,providers 先负责告诉前端“当前 City 真的开放了哪些登录方式,以及它属于 oauth 还是 input 流程”;login/start 创建一次登录流程并返回下一步;login/continue 提交 input 流程需要的输入;login/result 统一读取最终 user_token。
GET /v1/accounts/providers 是面向客户端的已启用列表。provider 虽然已经在代码里挂载,但如果缺少 required env 或 runtime 配置,就不会出现在这里。配置目录和缺失项仍然通过 Federation env catalog 或 admin workspace 查看。
oauth 流程会在 login/start 返回授权 URL;input 流程会在 login/start 返回当前步骤的 inputs,例如 email 需要 email/password。Local Account 也是 input 流程,只是 inputs 为空,并且 login/start 会直接返回 status: "done"。无论哪一种,最终都通过 login/result 读取 token。
当前官方 accounts service 可以按服务端配置开放邮箱、GitHub、Google、WeChat 网站应用登录。前端应该始终以 providers 返回为准,不要把登录按钮写死。
如果你现在要真正把 Google 登录配起来,继续读 Google 登录配置。
如果你现在要真正把微信网站登录配起来,继续读 微信登录配置。
me 和 logout
这两个动作已经属于用户态,不再是 guest 入口。
const me = await user.service("accounts").get("me");
await user.service("accounts").action("logout").invoke();session 在这里的意义
即使产品最终主要靠 user_token 调 City,账号系统仍然需要:
- better-auth 认证事实表
- session 表
- 登录态相关事实
- 产品层 profile 资料
这也是为什么 service 不只是“几个路由”,而是一套完整账号基础设施的最小实现。
挂载 AccountsService 不等于所有登录方式都可用。邮箱登录需要 email provider 和验证邮件发送能力;OAuth 登录需要对应 OAuth provider 和 client credentials。
me 现在返回什么
GET /v1/accounts/me 不再只返回运行时 user,还会一起返回:
profile:产品层展示资料,例如展示名、头像、简介
这样产品前端和管理侧都不需要再自己去拼认证表。