短期 Web Login Ticket
短期 Web Login Ticket 用于把桌面端或移动端已有的 OAuth 登录状态一次性传给浏览器,并兑换成网站现有 User Session。它不新增 OAuth grant,也不建立另一套 Session。
text
OAuth access token -> 60 秒 ticket -> 浏览器一次性消费 -> 网站 User Session签发
http
POST /auth/web-login/tickets
Authorization: Bearer <wno-access-token>
Content-Type: application/json
{ "target": "personal-security" }json
{
"loginUrl": "https://frontend.example/auth/web-login#ticket=wn-web-...",
"expiresIn": 60
}OAuth token 必须包含 auth:web-login scope。这个能力由 OAuth App 管理面独立授权,后端不登记 client ID。当前只支持固定目标 personal-security,对应网站稳定入口 /settings/personal/security;调用方不需要也不应该传 teamSlug。
消费
http
POST /auth/web-login/consume
Content-Type: application/json
{ "ticket": "wn-web-..." }成功响应中的 user、session、created 与网站现有手机号/微信登录返回结构一致。ticket 默认 60 秒有效,只能消费一次。
签发端缺少 scope 返回 insufficient_scope;账号未激活返回 invite_activation_required。消费端常见错误:ticket_invalid、ticket_expired、ticket_consumed、ticket_node_mismatch、oauth_authorization_revoked、service_unavailable。
复用规则
- ticket 原文只返回一次,数据库只保存 SHA-256 hash。
- ticket 绑定用户、OAuth token、client、固定 target、节点模式和前端 origin。
- 浏览器 URL 使用 fragment;网站在 router 启动前捕获并立即清除 fragment。
- 消费时原子标记已使用,并再次确认原 OAuth 授权和
auth:web-loginscope 仍有效。 - 新增目标时扩展固定 target 枚举并由网站映射到站内路由,不接受任意跳转 URL,不复制新的 Session 实现。
完整实现说明与复用检查项见仓库开发文档 docs/features/auth/web-login-ticket.md。
修改密码
网页登录完成后使用网站 User Session 调用:
http
POST /my/password/change
Authorization: Bearer <user-session>
Content-Type: application/json
{ "currentPassword": "...", "newPassword": "..." }稳定错误码包括 current_password_invalid、password_not_configured、password_unchanged、invalid_request 和 service_unavailable。