You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ory Kratos设置流无法成功修改密码问题咨询

问题分析与解决方案

核心问题排查

  1. 流类型误用:页面标题是“Recover your password”,但代码中使用的是SelfServiceSettingsFlow(账号设置流)——这个流是给已登录用户修改账号信息用的,而密码恢复需要使用SelfServiceRecoveryFlow(密码恢复流)。流类型不匹配是导致密码未生效的根本原因。
  2. 表单提交逻辑缺失:当前代码仅处理了流的初始化和获取,没有处理表单提交后的响应。Ory Kratos在提交后会返回重定向或新流数据,若不处理这些响应,就会出现“提示成功但实际未生效”的情况。

具体修复步骤

1. 替换为密码恢复流

修改原SettingsVue.vue(建议重命名为PasswordRecovery.vue),将设置流替换为恢复流:

<template>
  <div id="password-recovery">
    <HomeTopbar :views="[]" />

    <div class="recovery-wrapper">
      <h1 class="poppins fs_3 fw_6">Recover your password</h1>
      <OryFlow v-if="recoveryFlow"
        :flow="recoveryFlow"
        form-id="recovery-form"
        @update:flow="updateFlow"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

import { injectStrict } from '@/utils';
import { $ory } from '@/plugins/ory';
import { makeHandleGetFlowError } from '@/utils/flows';

import type { SelfServiceRecoveryFlow } from '@ory/kratos-client';

import { useRoute, useRouter } from 'vue-router';

import OryFlow from '@/components/flows/OryFlow.vue';
import HomeTopbar from '@/components/ui/HomeTopbar.vue';

const ory = injectStrict($ory);
const route = useRoute();
const router = useRouter();
const recoveryFlow = ref<SelfServiceRecoveryFlow | undefined>();
const handleGetFlowError = makeHandleGetFlowError(router);

const { flow } = route.query;

const updateFlow = (newFlow: SelfServiceRecoveryFlow) => {
  recoveryFlow.value = newFlow;
};

const initializeSelfServiceRecoveryFlowForBrowsers = () =>
  ory
    .initializeSelfServiceRecoveryFlowForBrowsers()
    .then((response) => {
      recoveryFlow.value = response.data;
      router.replace({
        query: {
          flow: response.data.id,
        },
      });
    })
    .catch(handleGetFlowError);

if (typeof flow !== 'string') {
  initializeSelfServiceRecoveryFlowForBrowsers();
} else {
  ory
    .getSelfServiceRecoveryFlow(flow)
    .then((response) => {
      recoveryFlow.value = response.data;
    })
    .catch(handleGetFlowError);
}
</script>

<style scoped lang="scss">
#password-recovery {
  width: 100%;
  height: 100%;

  .recovery-wrapper {
    margin: var(--space-5) auto 0 auto;
    padding: 0 var(--space-3);
    margin-top: var(--space-4);
    width: 300px;
  }
}
</style>

2. 完善OryUiNode组件

确保OryUiNode正确渲染所有必填字段(尤其是CSRF令牌和密码输入框):

<template>
  <div v-if="node.type === 'input'" class="input-node">
    <label v-if="node.meta.label" :for="id" class="label">
      {{ node.meta.label.text }}
    </label>
    <input
      :id="id"
      :type="node.attributes.type"
      :name="node.attributes.name"
      :value="node.attributes.value || ''"
      :required="node.attributes.required"
      :placeholder="node.meta?.placeholder?.text || ''"
      class="input"
    />
    <span v-if="node.meta?.text" class="hint">{{ node.meta.text.text }}</span>
  </div>
  <button 
    v-else-if="node.type === 'button'" 
    :type="node.attributes.type"
    class="submit-btn"
  >
    {{ node.meta.label.text }}
  </button>
</template>

<script setup lang="ts">
import type { UiNode } from '@ory/kratos-client';

defineProps<{
  node: UiNode;
  id: string;
}>();
</script>

3. 添加表单提交处理逻辑

修改OryFlow.vue,通过Ory SDK处理表单提交,而非依赖浏览器默认行为:

<template>
  <div class="ory-flow">
    <form 
      :id="formId" 
      :action="flow.ui.action" 
      :method="flow.ui.method"
      @submit.prevent="handleSubmit"
    >
      <OryUiNode v-for="node in flow.ui.nodes"
        :key="getNodeId(node)"
        :id="getNodeId(node)"
        :node="node"
        class="ui-node"
        ref="uiNodes"
      />
    </form>
    <div class="messages" v-if="flow.ui.messages">
      <OryUiMessage v-for="message in flow.ui.messages" :message="message" />
    </div>
  </div>
</template>

<script setup lang="ts">
import type {
  SelfServiceLoginFlow,
  SelfServiceRegistrationFlow,
  SelfServiceRecoveryFlow,
  SelfServiceSettingsFlow,
  SelfServiceVerificationFlow,
} from '@ory/kratos-client';
import OryUiNode from './OryUiNode.vue';
import OryUiMessage from './OryUiMessage.vue';
import { getNodeId } from '@ory/integrations/ui';
import { injectStrict } from '@/utils';
import { $ory } from '@/plugins/ory';
import { useRouter } from 'vue-router';

const props = defineProps<{
  flow:
    | SelfServiceLoginFlow
    | SelfServiceRegistrationFlow
    | SelfServiceRecoveryFlow
    | SelfServiceSettingsFlow
    | SelfServiceVerificationFlow;
  formId?: string;
}>();

const emit = defineEmits<{
  'update:flow': [flow: typeof props.flow];
}>();

const ory = injectStrict($ory);
const router = useRouter();
const uiNodes = ref<InstanceType<typeof OryUiNode>[]>([]);

const handleSubmit = async () => {
  const formData = new FormData();
  uiNodes.value.forEach(node => {
    const input = node.$el.querySelector('input, select, textarea');
    if (input) formData.append(input.name, input.value);
  });

  try {
    // 根据流类型调用对应提交方法
    if ('type' in props.flow && props.flow.type === 'recovery') {
      const response = await ory.submitSelfServiceRecoveryFlow(props.flow.id, 'browser', formData);
      if (response.status === 302) {
        router.push(response.headers.location || '/login');
      }
    } else if ('type' in props.flow && props.flow.type === 'settings') {
      const response = await ory.submitSelfServiceSettingsFlow(props.flow.id, 'browser', formData);
      if (response.status === 302) {
        router.push(response.headers.location || '/dashboard');
      }
    }
  } catch (error: any) {
    // 提交失败时更新流的错误信息
    if (error.response?.data?.ui) {
      emit('update:flow', error.response.data);
    }
  }
};
</script>

<style scoped lang="scss">
.ui-node + .ui-node {
  margin-top: var(--space-2);
}

.messages {
  margin-top: var(--space-2);
}
</style>

4. 验证Kratos配置

确保Kratos配置文件中启用了密码恢复功能:

# kratos.yml 示例配置
selfservice:
  recovery:
    enabled: true
    methods:
      password:
        enabled: true

总结

核心问题是流类型误用:密码恢复需要使用SelfServiceRecoveryFlow而非设置流。同时,必须通过Ory SDK处理表单提交,才能正确响应Kratos的重定向或错误反馈,确保操作真正生效。

内容的提问来源于stack exchange,提问作者TheHiggsBroson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:07:03