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

Kratos注册时404错误求助:搭建仅用户名密码认证系统问题

问题:Next.js 13集成Kratos注册请求返回404错误

我是Kratos新手,想搭建一个仅用用户名密码完成注册/登录的简单认证系统,但在Next.js 13提交注册请求时收到404错误,提示"Unable to locate the resource"。以下是相关代码配置:

Next.js页面代码

"use client";
import { useEffect, useRef, useState } from "react";
import { useSearchParams } from "next/navigation";
import { Configuration, FrontendApi } from "@ory/client";
import { edgeConfig } from "@ory/integrations/next";

const ory = new FrontendApi(new Configuration(edgeConfig));

function getCsrfTokenFromApiResponse(response) {
  try {
    const csrfToken = response?.data?.ui?.nodes?.find(
      (node) => node.attributes?.name === "csrf_token"
    )?.attributes?.value;
    return csrfToken || null;
  } catch (error) {
    console.error("Error while parsing the API response:", error);
    return null;
  }
}

function getFlowIdFromApiResponse(response) {
  try {
    const flowId = response?.data?.id;
    return flowId || null;
  } catch (error) {
    console.error("Error while parsing the API response:", error);
    return null;
  }
}


export default function Register() {
  const searchParams = useSearchParams();
  console.log(" searchParams", searchParams?.getAll);
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const flow = useRef("");
  const csrfToken =  useRef("");

  useEffect(() => {
    const fetchFlow = async () => {
      const data = await ory.createBrowserRegistrationFlow();
      csrfToken.current = getCsrfTokenFromApiResponse(data);
      flow.current = getFlowIdFromApiResponse(data);
      console.log(data);
    };
    fetchFlow();
  }, []);

  const handleSubmit = async (event) => {
    event.preventDefault();

    var myHeaders = new Headers();
    myHeaders.append("Content-Type", "application/json");
    myHeaders.append("X-CSRF-Token", csrfToken.current);

    var raw = JSON.stringify({
      method: "password",
      traits: {
        username,
      },
      password,
      csrf_token: csrfToken.current,
    });

    var requestOptions = {
      method: "POST",
      headers: myHeaders,
      body: raw,
      redirect: "follow",
    };

    fetch(
      `http://127.0.0.1:4433/self-service/registration?flow=${flow.current}`,
      requestOptions
    )
      .then((response) => response.text())
      .then((result) => console.log(result))
      .catch((error) => console.log("error", error));
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Username:
        <input
          type="text"
          value={username}
          onChange={(event) => setUsername(event.target.value)}
        />
      </label>
      <br />
      <label>
        Password:
        <input
          type="password"
          value={password}
          onChange={(event) => setPassword(event.target.value)}
        />
      </label>
      <br />
      <button type="submit">Register</button>
    </form>
  );
}

身份Schema

{
  "$id": "https://schemas.ory.sh/presets/kratos/quickstart/username-password/identity.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "UsernamePassword",
  "type": "object",
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        "username": {
          "type": "string",
          "format": "string",
          "title": "username",
          "minLength": 8,
          "maxLength": 30,
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            }
          }
        }
      },
      "required": ["username"],
      "additionalProperties": false
    }
  }
}

Kratos配置

version: v0.13.0

dsn: memory

serve:
  public:
    base_url: http://127.0.0.1:4433/
    cors:
      enabled: true
      allow_credentials: true
      allowed_origins:
        - http://127.0.0.1:4433
        - http://*127.0.0.1:4433
        - http://localhost:3000
        - http://*.localhost:3000
      allowed_methods:
        - POST
        - GET
        - PUT
        - PATCH
        - DELETE
      allowed_headers:
        - Authorization
        - Cookie
        - Content-Type
        - X-Session-Token
        - X-Csrf-Token
      exposed_headers:
        - Content-Type
        - Set-Cookie
      debug: true
  admin:
    base_url: http://0.0.0.0:4434/

selfservice:
  default_browser_return_url: http://localhost:3000/
  allowed_return_urls:
    - http://localhost:3000

  methods:
    password:
      enabled: true

  flows:
    login:
      ui_url: http://localhost:3000/auth/login

    registration:
      ui_url: http://localhost:3000/auth/registration

    settings:
      ui_url: http://localhost:3000/auth/settings

    recovery:
      enabled: false
      
log:
  level: debug

secrets:
  cookie:
    - PLEASE-CHANGE-ME-I-AM-VERY-INSECURE

identity:
  default_schema_id: default
  schemas:
    - id: default
      url: file:///etc/config/kratos/identity.schema.json

courier:
  smtp:
    connection_uri: smtps://test:test@mailslurper:1025/?skip_ssl_verify=true

我已按照Kratos文档添加了/api/.ory/[..path].ts,希望有人指出错误原因,并提供实现该系统的更好方案。


错误原因与优化方案

错误原因分析

  1. 请求路径错误:Kratos处理注册提交的正确端点是/self-service/registration/flows/{flow-id},而非你当前使用的/self-service/registration,错误路径直接导致404。
  2. 直接调用Kratos API的风险:虽然配置了CORS,但前端直接调用Kratos公共API存在安全隐患,且没有利用已配置的Next.js API路由代理。
  3. Flow处理逻辑不严谨:未处理flow过期、获取失败等场景,可能导致使用无效flow ID发起请求。

修正后的实现方案

1. 修正注册请求端点

将handleSubmit中的fetch URL改为正确路径:

`http://127.0.0.1:4433/self-service/registration/flows/${flow.current}`

2. 利用Next.js API路由代理(推荐)

通过已配置的/api/.ory/[..path].ts代理请求,避免直接暴露Kratos地址:

fetch(
  `/api/.ory/self-service/registration/flows/${flow.current}`,
  requestOptions
)

3. 优化Flow获取与错误处理

更新flow获取逻辑,增加错误处理:

useEffect(() => {
  const fetchFlow = async () => {
    try {
      const data = await ory.createBrowserRegistrationFlow();
      csrfToken.current = getCsrfTokenFromApiResponse(data);
      flow.current = getFlowIdFromApiResponse(data);
      if (!flow.current) throw new Error("Failed to get valid flow ID");
    } catch (error) {
      console.error("Failed to fetch registration flow:", error);
      // 可添加UI错误提示或重试逻辑
    }
  };
  fetchFlow();
}, []);

4. 使用Ory Client简化提交逻辑

无需手动构造fetch请求,直接调用Ory Client方法减少错误:

const handleSubmit = async (event) => {
  event.preventDefault();
  try {
    await ory.updateRegistrationFlow({
      flow: flow.current,
      updateRegistrationFlowBody: {
        method: "password",
        traits: { username },
        password,
        csrf_token: csrfToken.current,
      },
    });
    window.location.href = "/"; // 注册成功后跳转
  } catch (error) {
    console.error("Registration failed:", error);
    // 显示错误信息给用户
  }
};

5. 验证Kratos配置

确认Kratos服务正常运行在http://127.0.0.1:4433,且身份schema文件路径正确,确保Kratos能加载到schema。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:18:11