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

NextAuth.js集成Keycloak与自定义基础路径时登出遇CSRF请求失败错误

NextAuth.js(v4.24.11)集成Keycloak自定义基础路径下登出报错:Failed to fetch /api/auth/csrf

问题描述

在使用NextAuth.js(v4.24.11)集成Keycloak并配置自定义基础路径时,执行登出操作出现控制台错误:Failed to fetch /api/auth/csrf

已尝试的排查步骤

  • 确认.env中的NEXTAUTH_URL已正确设置为匹配自定义基础路径
  • 手动验证csrf端点,发现该端点无法访问
  • 设置NEXTAUTH_DEBUG=true以获取更多日志,但未得到有效信息
  • 添加NODE_TLS_REJECT_UNAUTHORIZED=0用于本地测试,规避TLS问题
  • 确保所有路由都已正确添加基础路径前缀(/workflow-checkmate)

环境配置(ENV)

NEXTAUTH_URL=http://localhost:3000/workflow-checkmate/api/auth

错误详情

浏览器端错误截图

浏览器错误截图1
浏览器错误截图2

终端端错误截图

终端错误截图

认证选项(Auth Options)代码

import {
  KEYCLOAK_CLIENT_ISSUER,
  KEYCLOAK_CLIENT_SECRET,
  keycloakClientId,
  NEXTAUTH_SECRET,
} from "@/constants";
import { jwtDecode } from "jwt-decode";
import { NextAuthOptions } from "next-auth";
import KeycloakProvider from "next-auth/providers/keycloak";
import { refreshAccessToken } from "./utils/refreshAccessToken";
import { encrypt } from "./utils/encrypt-decrypt-auth";

export const authOptions: NextAuthOptions = {
  session: {
    strategy: "jwt",
  },
  secret: NEXTAUTH_SECRET,

  // PROVIDERS
  providers: [
    KeycloakProvider({
      clientId: keycloakClientId,
      clientSecret: KEYCLOAK_CLIENT_SECRET,
      issuer: KEYCLOAK_CLIENT_ISSUER,
    }),
  ],

  callbacks: {
    async redirect({ url, baseUrl }) {
      return url.startsWith(baseUrl)? url : baseUrl;
    },

    async jwt({ token, account }) {
      const nowTimeStamp = Math.floor(Date.now() / 1000);
      if (account) {
        token.decoded = jwtDecode(account.access_token?? "");
        token.access_token = account.access_token?? "";
        token.id_token = account.id_token?? "";
        token.expires_at = account.expires_at?? 0;
        token.refresh_token = account.refresh_token?? "";
        return token;
      } else if (nowTimeStamp < token.expires_at) {
        return token;
      } else {
        try {
          console.log("Refreshing access token");
          const refreshedToken = await refreshAccessToken(token);
          console.log("Access token refreshed");
          return refreshedToken;
        } catch (error) {
          console.error("Error refreshing access token", error);
          return {...token, error: "RefreshAccessTokenError" };
        }
      }
    },
    async session({ session, token }) {
      session.access_token = encrypt(token.access_token);
      session.id_token = encrypt(token.id_token);
      session.error = token.error;
      session.user.id = token.sub;
      session.user.name = token.name;
      session.user.email = token.email;
      return session;
    },
  },

  // DEBUG
  debug: true,
  logger: {
    error(code, metadata) {
      console.log(code, metadata);
    },
    warn(code) {
      console.log(code);
    },
    debug(code, metadata) {
      console.log(code, metadata);
    },
  },
};

会话提供者(SESSION PROVIDER)代码

"use client";
import { Session } from "next-auth";
import { SessionProvider } from "next-auth/react";
import React from "react";

type props = {
  children: React.ReactNode;
  session?: Session | null;
};
export default function SessionProviderWrapper({ children, session }: props) {
  return (
    <SessionProvider session={session} basePath={`workflow-checkmate/api/auth`}>
      {children}
    </SessionProvider>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 21:08:09