修改初始密码

在企业应用安全管理规范中,通常会在新用户被初始化导入或管理员后台重置密码后,限制其以默认或初始密码访问系统。当系统检测到用户需要更改初始密码时,会引导用户访问修改初始密码专属页面。

本文将以 Simple 模板中的 src/views/account/initial.vue 文件为核心,详细介绍修改初始密码的场景、认证凭证截取、密码更新接口以及修改成功后的后续业务链路。

使用场景与触发机制

当用户使用系统生成的初始密码登录成功,或是接收到系统的重置邮件链接时,会进入修改初始密码的引导逻辑。该功能在前端采用 uniboot-ui 提供的内置面板 InitialPage 进行展示。

其对应的页面模板结构如下:

html
<template>
  <initial-page
    :logo="runtimeConfig.web_logo"
    :page-title="$t('changeInitialPassword')"
    :sub-title="subTitle"
    :product-title="staticConfig.title"
    :new-password-label="$t('user.changePwd.newPwd')"
    :confirm-password-label="$t('user.changePwd.confirmPwd')"
    :submit-text="$t('confirm')"
    :password-tips="passwordTips"
    :auth-code="authCode"
    :on-submit="handleSubmit"
    :languages="languages"
    :default-language="currentLocale"
    :on-language-change="handleLanguageChange"
    :enter-message="$t('enter')"
    :password-format-message="$t('wrong_format')"
    :confirm-mismatch-message="$t('twice_inconsistent')"
  />
</template>

核心业务链路

1. 认证凭证解析

在加载修改初始密码页面时,页面通常需要具备权限校验凭据,用来证明当前修改请求是经过授权的。

  • 参数来源: 从当前的 URL 查询参数中截取 code 字段。
  • 获取方法: 在组件中,通过调用公共的 URL 参数提取函数 getParam('code') 来实时读取凭证,并赋值给 authCode 变量。
typescript
// 从 URL 的 Query 参数中获取鉴权 code 值,如 /account/initial?code=xxx
const authCode = computed(() => getParam('code') || '')

2. 初始密码修改提交

用户在表单面板中输入新密码并重复确认无误后,点击提交按钮。

  • 业务逻辑: 调用绑定的 handleSubmit 方法。
  • API 通信: 调用本地服务接口 changeInitPassword。向接口传递 authCode(表单返回的认证凭据或 URL 查询参数中兜底读取的值)以及 newPassword(符合规范复杂度的新密码文本)。
typescript
const handleSubmit = async (values: InitialPasswordSubmitValues) => {
  // 调用安全接口更改初始密码
  await changeInitPassword({
    authCode: values.authCode ?? getParam('code'),
    newPassword: values.newPassword,
  })

  // 密码更新后的登出动作
  setTimeout(() => {
    userStore.logout()
  }, 3000)
}

3. 密码成功修改后的强制登出

为了确保用户已使用新密码激活新的会话,并避免因旧凭据缓存导致的前后端授权不同步问题,系统执行了强制登出逻辑:

  • 延迟执行: 使用 setTimeout 延迟 3000ms(3秒)执行。
  • 登出逻辑: 调用 userStore.logout() 清理当前 Pinia store 和 localStorage/Cookie 内的前端状态数据,并强行导向登录页面,从而让用户在友好的 Toast 提示消息展示完毕后,可以使用新设置的密码重新登录系统。

辅助逻辑设计

UI 配置动态载入

  • 系统 Logo 与标题: Logo 从 App 状态管理模块中的 runtimeConfig.web_logo 中动态读取;副标题利用静态配置文件的软件名配置结合多语言工具进行合成:
    typescript
    const subTitle = computed(() =>
      t('changeInitialPassword.desc', { title: staticConfig.title })
    )
  • 密码复杂度规则展示: 通过 passwordTips 传入当前设定的密码安全条件,在界面中以列表项展示,辅助用户设置高强度的安全密码:
    typescript
    const passwordTips = computed(() => [
      t('user.changePwd.tip1'),
      t('user.changePwd.tip2'),
      t('user.changePwd.tip3'),
      t('user.changePwd.tip4'),
    ])

多语言切换强刷

当发生语言变更时,为确保新选择的字典及整个登录拦截组件中静态文本得到重载,通过调用 reload 使其页面重刷:

typescript
const handleLanguageChange = async (value: string) => {
  // 切换 i18n 语言标识
  setI18nLanguage(value)
  // 重载当前窗口以重置渲染环境
  window.location.reload()
}