快速结论:使用 OIDC SSO 登录的 n8n 自托管实例,在未登录状态下打开受保护深链(如 /form/… 或 /workflow/…)时,登录完成后会被强制跳回 /home/workflows,原始目标页丢失。优先排查方向是后端 OIDC 回调是否具备持久化并还原 return_target 的事务逻辑,而不是前端按钮或代理配置。
适用环境:n8n 2.26.3,Node.js v24.15.0,PostgreSQL,Docker 运行于 Alpine 3.22,self hosted,执行模式为 main(默认)。认证方式为 OIDC SSO。
最快修复方案:暂无确认的一步修复方案。Issue 讨论中给出的方向是把原始跳转目标绑定为 OIDC 事务属性(与 state 一次性关联),在回调时消费事务后再重定向,但这属于设计建议,尚未有已发布版本验证。
注意事项:不要直接把未校验的绝对 URL 塞进回调做跳转,否则可能形成开放重定向。Issue 中已排除 IdP state 丢失、角色映射失败、SameSite 配置、代理/入口清洗以及特定路由问题,因此继续调这些方向大概率无效。
问题场景
在 n8n 自托管实例上启用 OIDC SSO 后,用户以未登录状态点击外部发来的深链(例如 Slack、Jira、邮件中的表单链接 /form/example-form?issue=EXAMPLE-123 或工作流链接 /workflow/<id>)。n8n 会先把请求拦截并跳转到 /signin?redirect=<target>,用户点击 SSO 登录并在 IdP 完成认证后,本应回到原始目标页。
问题出现在 OIDC 流程返回 n8n 之后:前端 SSO 按钮没有把 redirect 参数传给后端;即使手动把 redirect 传给后端登录端点 /rest/sso/oidc/login?redirect=<target>,回调完成后仍然忽略该参数。
报错原文
[Bug]: OIDC SSO deep-link redirect is lost after login; callback returns 302 Location: /
302 Location: /
原因分析
最可能的原因:n8n 后端 OIDC 流程缺少状态管理逻辑,无法在认证前保存深链目标、在回调时读取并还原。报告作者明确说明这不是单纯的前端 UI 问题,因为直接把 redirect 传给后端登录端点后,callback 依然返回硬编码的 302 Location: /。
Issue 中已逐项排除以下可能原因:IdP 未回传 state、认证/角色映射失败、SameSite Cookie 被丢弃、代理/Ingress 清洗参数、特定路由差异。因此这些方向不再是主要怀疑对象。
讨论中的社区建议进一步指出,正确做法应把返回目标作为 OIDC 一次性事务属性绑定到 state,而不是作为独立参数穿过 callback。这样才能同时满足“保留用户原始意图路径与查询串”和“只允许跳回 n8n 允许过的目标”两个不变量。
环境排查
- 确认 n8n 版本:Issue 中为 2.26.3。
- 确认 Node.js 版本:Issue 中为 v24.15.0。
- 确认数据库为 PostgreSQL。
- 确认运行方式为 Docker,基础镜像 Alpine 3.22,执行模式 main(默认),self hosted。
- 确认 OIDC SSO 已启用,并确认 IdP 侧 state 回传正常。
- 确认
N8N_LOG_LEVEL=debug下能看到 OIDC 客户端配置与 SSO 角色解析完成且无报错。 - 确认访问路径为受保护深链(/form/… 或 /workflow/…),而非公开页面。
解决步骤
- 先按 Issue 的两个测试复现:正常 UI 流程(打开深链 → /signin?redirect=… → SSO → 观察落点)与直接后端测试(手动访问
/rest/sso/oidc/login?redirect=%2Fworkflow%2F<workflow-id>)。两者都落到 /home/workflows 即复现成功。 - 抓取 OIDC 登录到 callback 的完整请求链,确认回调响应头确实是
302 Location: /,而不是被 IdP 或代理改写。 - 确认前端 SSO 按钮是否把 redirect 传给后端;Issue 证据显示它没有传。
- 即使手动给后端 login 端点补上 redirect,回调仍忽略它,说明需要后端在认证事务中保存目标。可优先尝试的方向是:在创建认证事务时记录规范化后的相对 return_target,并将其引用编码进 OIDC state,callback 校验 state 后一次性消费该事务并跳转到存储的目标。
- 若无法改动后端(例如等待官方修复),可作为临时绕过手段:登录完成后由用户手动返回原深链;或在外部通知里同时附上目标链接,方便认证后再次点击。此绕过未在 Issue 中验证。
验证方法
修复后应验证以下回归场景是否全部通过:
/workflow/<id>深链登录后回到该工作流。/form/<path>?issue=EXAMPLE-123登录后回到该表单,且查询串完整保留。- 过期或被重放的 state 应回退到默认页,不执行重定向。
- 外部目标(如
https://evil.example)应被拒绝或回退,避免开放重定向。 - 同时发起两个登录事务时,各自应回到自己的目标,而不是共用同一个全局/会话级 redirect 槽位导致串号。
只要其中任一场景未通过,说明修复尚未完整。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![issue: [regression] [dev] someone removed from the group keeps a chat shared with "Allow replies" open again](https://www.chat-gpts.plus/wp-content/uploads/2026/10/32527-73cee0cc-768x403.jpg)

