Skip to content

已登录改密码 ​

auth.settings 命名空间提供已登录用户的 step-up 改密流程(邮件验证码 → 改密)。它与 auth.reset 是两个正交场景的 namespace,详见下文「与 auth.reset 的差异」。

这两个 namespace 用错会出大问题

  • 已登录用户改密码用 auth.reset → 改完原 session 失效,用户被踢出去重新登录(v2 reset 设计意图就是「未登录恢复」)
  • 未登录用户恢复密码用 auth.settings → sendVerifyCode 在 createBrowserLoginFlow({ refresh: true }) 时就抛 401,跑不动

判据:dialog 入口在哪。登录页的「忘记密码」链接 → auth.reset;用户中心 / 设置页里的改密 dialog → auth.settings。

三段流程 ​

  1. auth.settings.sendVerifyCode({ email }) — 创建 ory login flow with refresh=true + method=code,下发邮件
  2. auth.settings.verifyCode({ code }) — 提交验证码完成 refresh login flow,当前 session 被标记为 privileged
  3. auth.settings.updatePassword({ newPassword }) — 在 privileged session 内走 settings flow 改密码,session 保持不变

底层依次走 ory createBrowserLoginFlow({ refresh: true }) → updateLoginFlow(method: 'code', identifier) → updateLoginFlow(method: 'code', code, identifier) → createBrowserSettingsFlow → updateSettingsFlow(method: 'password', password)。SDK 内部维护「当前活跃的 refresh login flow」串起前两段。

最短链路 ​

ts
import { TripoAuth, TripoAuthError } from '@tripo3d/auth';

const auth = new TripoAuth({
  basePath: 'https://auth.tripo3d.ai',
});

// 前置:用户已登录(auth.token.peek() 非空)

// 1. 给当前用户的注册邮箱发 step-up 验证码
await auth.settings.sendVerifyCode({ email: 'user@example.com' });

// 2. 用户拿到邮件验证码 → 提交完成 session 提权
await auth.settings.verifyCode({ code: '123456' });

// 3. privileged session 内改密码;session 保持,业务继续走
try {
  await auth.settings.updatePassword({ newPassword: 'new-strong-password' });
} catch (err) {
  if (err instanceof TripoAuthError && err.name === 'PRIVILEGED_SESSION_EXPIRED') {
    // 用户在 verifyCode 与 updatePassword 之间停太久(ory privileged_session_max_age 默认 15 min)
    // → 业务侧引导回 sendVerifyCode 重发验证码
  }
}

与 auth.reset 的差异 ​

维度auth.reset.*auth.settings.*
起点 session无(忘记密码场景)有(已登录改密码场景)
底层 ory flow 链recovery → settings,拆 3 段(sendCode·verifyCode·submitNewPassword)login(refresh=true) → settings,拆 3 段
公开方法数3(sendCode / verifyCode / submitNewPassword)3(sendVerifyCode / verifyCode / updatePassword)
改完 session替换/失效(业务方常引导重登)保持原 session
是否写登录信号 cookie否否
典型 UI两屏:① email + 验证码 → ② 新密码两屏:① 验证码 → ② 新密码
中间态 sharp edge有:verifyCode 后的 privileged session 过期窗口有:privileged session 默认 15 min 过期窗口

Vue 接入示例(两屏 UX,与产品交互对齐) ​

vue
<!-- Stage 1: 邮箱验证 -->
<script setup lang="ts">
const { $auth } = useNuxtApp();
const emit = defineEmits<{ (e: 'switchState', s: 'ResetPassword'): void }>();
const userStore = useUserStore();
const code = ref('');

const sendCode = (target: { email: string }) => $auth.settings.sendVerifyCode(target);

const onSubmit = async () => {
  try {
    await $auth.settings.verifyCode({ code: code.value });
    emit('switchState', 'ResetPassword');
  } catch (err) {
    // FLOW(验证码错 / 频控 / 过期):toast 提示,留在本页让用户重输或重发
    handleAuthError(err);
  }
};
</script>

<template>
  <DialogPersonalResetPasswordFieldEmail
    disabled
    :model-value="userStore.detail.email"
  />
  <DialogPersonalResetPasswordFieldCode
    v-model="code"
    :send-code="sendCode"
  />
  <Button @click="onSubmit">下一步</Button>
</template>
vue
<!-- Stage 2: 新密码 -->
<script setup lang="ts">
const { $auth } = useNuxtApp();
const emit = defineEmits<{ (e: 'switchState', s: 'ValidEmail'): void }>();
const password = ref('');

const onSubmit = async () => {
  try {
    await $auth.settings.updatePassword({ newPassword: password.value });
    toast.success($t('phrase.password_reset_successful'));
    // session 没变,业务继续走
  } catch (err) {
    if (err instanceof TripoAuthError && err.name === 'PRIVILEGED_SESSION_EXPIRED') {
      // 提权过期:toast + 回上一步重发验证码
      toast.error($t('phrase.session_expired_resend_code'));
      emit('switchState', 'ValidEmail');
      return;
    }
    handleAuthError(err);
  }
};
</script>

API 参考 ​

方法签名说明
auth.settings.sendVerifyCode(args: { email }) => Promise<void>创建 ory login flow with refresh=true + method=code;触发邮件下发;flow id + csrf + identifier 写入实例级 holder
auth.settings.verifyCode(args: { code }) => Promise<void>在 refresh login flow 上提交 code → 当前 session 被标记为 privileged;成功后清 holder
auth.settings.updatePassword(args: { newPassword }) => Promise<void>privileged session 内走 settings flow 改密码;session 保持;不写登录信号 cookie

常见错误 ​

完整错误分类见 错误处理:

  • FLOW — 验证码错(verifyCode)/ 新密码强度不达标(updatePassword 被 ory 拒);message 直接 toast
  • NETWORK — fetch 抛错 / HTTP 5xx
  • VALIDATION — verifyCode 在没先 sendVerifyCode 的情况下被调用
  • PRIVILEGED_SESSION_EXPIRED — updatePassword 时当前 session 未提权或提权已过期(ory privileged_session_max_age,默认 15 min)。业务侧应 toast 提示 + 把 UI 切回 sendVerifyCode 一步
  • INTERNAL — flow ui 节点取不到 csrf_token(理论上 ory 不应出现)

下一步 ​

基于 MIT 协议发布(内部使用)