首页  >  问答  >  正文

无法成功更改密码的Ory Kratos设置流程

<p>我为Ory Kratos设置流程创建了自己的用户界面。我遇到的问题是,尽管返回的消息显示我的设置已成功更新,但我的新密码没有反映出来,我也没有成功恢复我的账户。以下是我使用Vue 3渲染UI的代码片段。</p> <pre class="brush:js;toolbar:false;">// SettingsVue.vue <template> <div id="settings"> <HomeTopbar :views="[]" /> <div class="settings-wrapper"> <h1 class="poppins fs_3 fw_6">恢复您的密码</h1> <OryFlow v-if="settingsFlow" :flow="settingsFlow" title="登录" form-id="settings-form" /> </div> </div> </模板> <脚本设置lang=“ts”> 从“vue”导入{ref}; /* 理论 */ 从'@/utils'导入{injectStrict}; 从 '@/plugins/ory' 导入 { $ory }; 从'@/utils/flows'导入{makeHandleGetFlowError}; /* 类型 */ 从“@ory/kratos-client”导入类型{SelfServiceSettingsFlow}; /* 可组合项 */ 从 'vue-router' 导入 { useRoute, useRouter }; /* 成分 */ 从'@/components/flows/OryFlow.vue'导入OryFlow; 从 '@/components/ui/HomeTopbar.vue' 导入 HomeTopbar; 常量=injectStrict($ory); const 路由 = useRoute(); const 路由器 = useRouter(); const settingsFlow = ref(); const handleGetFlowError = makeHandleGetFlowError(路由器); // 检查我们是否有流参数 const { 流 } = 路线.query; constinitializeSelfServiceSettingsFlowForBrowsers = () =>; 奥里 .initializeSelfServiceSettingsFlowForBrowsers() .then((响应) => { settingsFlow.value = 响应.data; 路由器.替换({ 询问: { 流:response.data.id, }, }); }) .catch(handleGetFlowError); if (typeof flow !== 'string') { // 如果我们的路线中没有流量, // 我们需要初始化登录流程 初始化SelfServiceSettingsFlowForBrowsers(); } 别的 { 奥里 .getSelfServiceSettingsFlow(流) .then((响应) => { settingsFlow.value = 响应.data; }) .catch(handleGetFlowError); } </脚本> <样式范围 lang=“scss”> #设置 { 宽度:100%; 高度:100%; .settings-wrapper { 边距:var(--space-5) auto 0 auto; 填充:0 var(--space-3); 顶部边距:var(--space-4); 宽度:300px; } } </风格> </前>
#OryFlow.vue
<模板>
  <div class="ory-flow">
    <表单:id="formId" :action="flow.ui.action"; :method="flow.ui.method">
      <OryUiNode v-for=“flow.ui.nodes 中的节点”
        :key="getNodeId(节点)"
        :id="getNodeId(节点)"
        :node="节点"
        class="ui-node";
      >>
    </表格>
    
<OryUiMessage v-for=“flow.ui.messages 中的消息” :message="消息" >>
; </模板> <脚本设置lang=“ts”> 导入类型{ 自助服务登录流程, 自助服务注册流程, 自助服务恢复流程, 自助服务设置流程, 自助服务验证流程, 来自“@ory/kratos-client”; 从 './OryUiNode.vue' 导入 OryUiNode; 从 './OryUiMessage.vue' 导入 OryUiMessage; 从 '@ory/integrations/ui' 导入 { getNodeId }; 定义属性<{ 流动: |自助服务登录流程 |自助服务注册流程 |自助服务恢复流程 |自助服务设置流程 |自助服务验证流程; 表单ID?:字符串; }>(); </脚本> <样式范围 lang=“scss”> .ui-节点 + .ui-节点 { 顶部边距:var(--space-2); } 。信息 { 顶部边距:var(--space-2); } </风格> </前>
P粉776412597P粉776412597414 天前547

全部回复(1)我来回复

  • P粉029327711

    P粉0293277112023-09-01 17:13:19

    所以解决这个问题实际上非常直接和明显,我在回顾Ory团队创建和维护的React自助服务UI的源代码后,这一点变得明显。

    如果你将所有UI节点组一起提交到同一个表单中,它只会在default组和另一个组上执行。在我的情况下,在成功处理profile组后,它忽略了password组。我遵循的解决方案基本上与我在前一段提到的存储库中提供的解决方案相同。实现一个过滤机制,允许您使用两个单独的表单,从而在提交表单时分离这些值。请记住,您必须始终提交default组,因为它包括您的CSRF令牌

    这是解决我的问题的更新代码:

    首先,添加对:only属性的支持,用于过滤节点:

    // OryFlow.vue现在支持通过'only'属性进行过滤
    <template>
      <div class="ory-flow">
        <form :id="formId"
          :action="flow.ui.action"
          :method="flow.ui.method"
        >
          <OryUiNode v-for="node in nodes"
            :id="getNodeId(node)"
            :key="getNodeId(node)"
            :node="node"
            class="ui-node"
          />
        </form>
        <div v-if="flow.ui.messages"
          class="messages"
        >
          <OryUiMessage v-for="message in flow.ui.messages"
            :key="message.id"
            :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 { computed, toRefs } from 'vue';
    
    const props = defineProps<{
      flow:
        | SelfServiceLoginFlow
        | SelfServiceRegistrationFlow
        | SelfServiceRecoveryFlow
        | SelfServiceSettingsFlow
        | SelfServiceVerificationFlow;
      formId?: string;
      only?: string | string[];
    }>();
    
    const { flow, only } = toRefs(props);
    
    const nodes = computed(() => {
      if (!only?.value) {
        return flow.value.ui.nodes;
      }
    
      const onlyArr: string[] = Array.isArray(only.value) ? only.value : [only.value];
      const onlyMap = onlyArr.reduce((acc, curr: string) => {
        acc[curr] = true;
        return acc;
      }, {} as Record<string, boolean>);
    
      return flow.value.ui.nodes.filter((node) => onlyMap[node.group]);
    });
    </script>
    

    接下来,在一个表单中利用这个新的属性来仅过滤节点组passworddefault。您可以使用相同的方法在另一个表单中过滤profiledefault

    // SettingsView.vue
    <template>
      <div id="settings">
        <HomeTopbar :views="[]" />
    
        <div class="settings-wrapper">
          <h1 class="poppins fs_3 fw_6">Recover your password</h1>
          <!-- 在这里添加only属性 -->
          <OryFlow v-if="settingsFlow"
            :flow="settingsFlow"
            title="Login"
            form-id="settings-form"
            :only="[ 'password', 'default' ]"
          />
        </div>
      </div>
    </template>
    

    回复
    0
  • 取消回复