
Double basePath is added to auth refresh redirect URLs when NEXT_PUBLIC_BASE_PATH is set
快速结论:这是一个已确认的 bug。当在 Next.js 项目中设置了 NEXT_PUBLIC_BASE_PATH 环境变量(例如 /workflow)时,服务端侧对 redirect() 函数的调用会重复添加 basePath,导致认证刷新或安装/初始化页面的跳转 URL 出现双重复前缀(如 /workflow/workflow/auth/refresh)。优先排查 web/app/(commonLayout)/hydration-boundary.tsx 中的 redirect() 调用是否手动拼接了 basePath。
问题场景
用户在使用 Dify 自托管(Self Hosted)版本 1.15.0,且部署在自定义子路径下(通过设置 NEXT_PUBLIC_BASE_PATH)。当触发服务端账户信息获取(位于 web/app/(commonLayout)/hydration-boundary.tsx)且该请求返回 401 状态码时,会导致浏览器被重定向至错误的 URL。
报错原文
# 错误的重定向行为
# 期望跳转到:
/workflow/auth/refresh?redirect_url=%2Fworkflow
# 实际跳转到:
/workflow/workflow/auth/refresh?redirect_url=%2Fworkflow
原因分析
该问题的根因是重复添加 basePath。Next.js 的 redirect() 函数会自动处理在 next.config.ts 中配置的 basePath,将其作为前缀添加到目标 URL 中。然而,在 web/app/(commonLayout)/hydration-boundary.tsx 文件中,开发者手动地、代码级别地将 ${basePath} 拼接到了传递给 redirect() 的参数前。这导致了双重添加:一次来自手动拼接,一次来自 Next.js 的自动处理。
具体来说,在文件第 45 行附近的代码如下:
redirect(`${basePath}${AUTH_REFRESH_PATH}?redirect_url=${encodeURIComponent(currentPath)}`)
当 NEXT_PUBLIC_BASE_PATH = "/workflow" 时:
- 手动拼接结果:
/workflow/auth/refresh - Next.js 自动添加
basePath后:/workflow+/workflow/auth/refresh=/workflow/workflow/auth/refresh
同样的问题也影响了同一文件中的另外两个 redirect() 调用(第 52-53 行),用于处理 not_setup 和 not_init_validated 状态码的跳转。
环境排查
- 工具/脚本:Dify 自托管版本 (v1.15.0)
- 配置环境变量:是否设置了
NEXT_PUBLIC_BASE_PATH - 关键文件:检查
web/app/(commonLayout)/hydration-boundary.tsx和web/next.config.ts
解决步骤
修复方法:移除对 redirect() 函数的手动 basePath 前缀拼接,让 Next.js 自动管理。
-
打开文件
web/app/(commonLayout)/hydration-boundary.tsx。 -
定位到第 45 行附近,将
AUTH_REFRESH_PATH相关的redirect()调用进行修改。移除手动拼接的${basePath}:- redirect(`${basePath}${AUTH_REFRESH_PATH}?redirect_url=${encodeURIComponent(currentPath)}`) + redirect(`${AUTH_REFRESH_PATH}?redirect_url=${encodeURIComponent(currentPath)}`) -
在同一文件中,定位到第 52 行附近的
not_setup处理逻辑,进行修改:- if (errorData?.code === 'not_setup') redirect(`${basePath}/install`) + if (errorData?.code === 'not_setup') redirect('/install') -
定位到第 53 行附近的
not_init_validated处理逻辑,进行修改:- if (errorData?.code === 'not_init_validated') redirect(`${basePath}/init`) + if (errorData?.code === 'not_init_validated') redirect('/init')
注意: 该文件中的
getCurrentPath()函数会正确地从请求头中读取浏览器实际路径(包含 basePath),因为它不是 Next.js 的redirect()目标,因此无需修改。
验证方法
完成上述修改后,重新构建并启动 Dify 前端服务。设置环境变量 NEXT_PUBLIC_BASE_PATH=/workflow,并复现问题场景(例如模拟一个返回 401 状态的账户信息请求)。检查浏览器是否被重定向至正确的 URL:/workflow/auth/refresh?redirect_url=%2Fworkflow 而非 /workflow/workflow/...。


![[BUG]: Error: SQLite database error](https://www.chat-gpts.plus/wp-content/uploads/2026/07/2564-70af5d26-768x403.jpg)
