P粉0293277112023-09-01 17:13:19
So solving this problem is actually pretty straightforward and obvious, which became apparent after I reviewed the source code for the React Self-Service UI created and maintained by the Ory team.
If you submit all UI node groups together into the same form, it will only execute on the default
group and one other group. In my case, after successfully processing the profile
group, it ignored the password
group. The solution I followed is basically the same as the one provided in the repository I mentioned in the previous paragraph. Implement a filtering mechanism that allows you to use two separate forms to separate the values when the form is submitted. Remember that you must always submit the default
group as it includes your CSRF token .
Here is the updated code that solved my problem:
First, add support for the :only
attribute for filtering nodes:
// 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>
Next, use this new attribute in a form to filter only the node groups password
and default
. You can use the same method to filter profile
and default
in another form.
// 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>