# ngrok内网穿透请求无法到达后端问题排查指南 ## 问题描述 - ✅ 请求能到达ngrok(在ngrok Traffic Inspector中可以看到) - ✅ 登录接口 `/api/wechat/login` 可以正常访问 - ❌ 其他接口如 `/api/wechat/case/stepCode/dealings` 无法到达后端 ## 可能原因分析 ### 1. **JWT Token认证问题(最可能)** **问题**:除了登录接口外,所有 `/wechat/**` 路径都需要JWT token认证。 **检查方法**: - 查看后端日志,看是否有 "jwt校验" 相关的日志 - 如果看到 "jwt校验失败" 或返回401状态码,说明请求被拦截器拦截了 **解决方案**: - 确保请求头中包含 `Authorization` 字段 - Token值格式应该是:`HDU xxxxxx`(根据JWT配置) ### 2. **ngrok路径配置问题** **问题**:ngrok可能配置了路径重写或只转发特定路径。 **检查ngrok配置**: ```bash # 检查ngrok配置文件(通常在用户目录下的.ngrok2/ngrok.yml) # 或者查看启动ngrok时的命令参数 ``` **正确的ngrok配置应该是**: ```yaml # ngrok.yml 示例 tunnels: backend: addr: 8080 # 后端服务端口 proto: http # 不要设置 bind_tls 或 path 参数,除非你确定需要 ``` **启动命令应该是**: ```bash ngrok http 8080 # 或者 ngrok http localhost:8080 ``` **错误的配置示例**(会导致路径问题): ```bash # ❌ 错误:如果设置了路径重写 ngrok http 8080 --host-header=rewrite # 或者配置了 path 参数 ``` ### 3. **后端context-path配置** **当前配置**: - `context-path: /api`(在application-dev.yaml中) - 这意味着所有接口的实际路径都是 `/api/xxx` **完整路径映射**: - 登录接口:`http://ngrok域名/api/wechat/login` ✅ - 问题接口:`http://ngrok域名/api/wechat/case/stepCode/dealings` ✅ ### 4. **请求路径不匹配** **检查点**: 1. 前端请求的完整URL是什么? 2. ngrok转发的目标地址是什么? **测试方法**: ```bash # 直接测试本地后端(绕过ngrok) curl -X GET "http://localhost:8080/api/wechat/case/stepCode/dealings?stepCode=500" \ -H "Authorization: HDU your-token-here" # 测试ngrok转发 curl -X GET "http://your-ngrok-domain.ngrok-free.dev/api/wechat/case/stepCode/dealings?stepCode=500" \ -H "Authorization: HDU your-token-here" ``` ## 排查步骤 ### 步骤1:检查后端日志 查看后端控制台日志,看是否有: - "拦截器拦截到请求" 日志 → 说明请求到达了后端 - "jwt校验" 日志 → 说明进入了拦截器 - 401错误 → 说明token验证失败 ### 步骤2:检查请求头 确保请求包含: ``` Authorization: HDU xxxxxx Content-Type: application/json ``` ### 步骤3:测试本地接口 绕过ngrok,直接访问本地接口: ```bash # 使用Postman或curl测试 GET http://localhost:8080/api/wechat/case/stepCode/dealings?stepCode=500 Headers: Authorization: HDU your-token-here ``` ### 步骤4:检查ngrok配置 1. 查看ngrok启动命令 2. 检查是否有路径重写配置 3. 确认ngrok转发到正确的端口(8080) ### 步骤5:检查ngrok Traffic Inspector 在ngrok的Traffic Inspector中: 1. 查看请求的完整路径 2. 查看请求头(特别是Authorization) 3. 查看响应状态码(如果是401,说明是认证问题) ## 常见解决方案 ### 方案1:添加请求日志(已添加) 已在拦截器中添加了详细的日志,重启后端后可以看到: - 请求URI - 请求方法 - Token是否存在 ### 方案2:临时禁用拦截器(仅用于测试) 如果需要测试,可以临时注释掉拦截器配置: ```java // 在 WebMvcConfiguration.java 中临时注释 // registry.addInterceptor(jwtTokenUserInterceptor) // .addPathPatterns("/wechat/**") // .excludePathPatterns("/wechat/login") // .excludePathPatterns("/wechat/loginTest","/wechat/esign/callback") // .excludePathPatterns("/wechat/file/download/**"); ``` **注意**:测试完后记得恢复! ### 方案3:检查ngrok的请求转发 如果ngrok显示请求成功(200),但后端没有日志,可能是: - ngrok缓存了响应 - ngrok配置了响应缓存 - 网络问题导致请求未到达后端 ## 新增诊断工具 ### 1. RequestLoggingFilter(已添加) 已在项目中添加了 `RequestLoggingFilter`,它会: - **在所有拦截器之前执行**,记录所有进入应用的请求 - 记录请求URI、方法、客户端信息、请求头、请求参数 - 如果这个Filter都没有日志输出,说明**请求根本没有到达Spring Boot应用** ### 2. 拦截器日志增强(已添加) 拦截器现在会记录: - 请求URI和HTTP方法 - Token是否存在 - JWT校验过程 ## 诊断步骤(按顺序执行) ### 步骤1:确认后端应用正在运行 ```bash # Windows PowerShell netstat -ano | findstr :8080 # 应该看到类似输出: # TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 12345 ``` 如果看不到8080端口在监听,说明后端应用没有启动或启动失败。 ### 步骤2:测试本地接口(绕过ngrok) 使用Postman或curl直接测试本地接口: ```bash # 测试登录接口(不需要token) curl -X POST "http://localhost:8080/api/wechat/login" \ -H "Content-Type: application/json" \ -d "{\"code\":\"test\"}" # 测试问题接口(需要token) curl -X GET "http://localhost:8080/api/wechat/case/stepCode/dealings?stepCode=500" \ -H "Authorization: HDU your-token-here" ``` **如果本地测试也失败**,说明是后端应用本身的问题,不是ngrok的问题。 ### 步骤3:检查ngrok配置和状态 ```bash # 检查ngrok是否正在运行 # 在ngrok的web界面查看:http://localhost:4040 # 检查ngrok转发的目标 # 应该显示:Forwarding https://xxx.ngrok-free.dev -> http://localhost:8080 ``` **重要检查点**: - ngrok转发的目标端口是否正确(应该是8080) - ngrok转发的目标地址是否正确(应该是 `http://localhost:8080` 或 `http://127.0.0.1:8080`) ### 步骤4:重启后端并查看日志 1. **重启后端应用** 2. **查看启动日志**,确认: - "RequestLoggingFilter 初始化完成" - Filter已加载 - "开始注册自定义拦截器..." - 拦截器已注册 - 应用监听在8080端口 3. **发送测试请求**(通过ngrok) 4. **查看日志输出**: - 如果看到 "========== 请求进入应用 ==========" → 请求到达了应用,继续查看后续日志 - 如果**完全没有日志** → 请求没有到达应用,问题在ngrok或网络层面 ### 步骤5:检查ngrok Traffic Inspector 在 `http://localhost:4040` 查看: 1. **请求是否出现在列表中**? - 如果不在列表中 → ngrok没有收到请求(前端问题) - 如果在列表中 → 继续下一步 2. **查看请求详情**: - **Request URL**: 完整的请求URL是什么? - **Request Headers**: 是否包含 `Authorization` 头? - **Response Status**: 返回的状态码是什么? - `200` → 请求成功,检查响应内容 - `401` → 认证失败,检查token - `404` → 路径不存在,检查URL - `502 Bad Gateway` → ngrok无法连接到后端 - `504 Gateway Timeout` → 后端响应超时 - 没有响应 → 请求可能被ngrok拦截或缓存 3. **查看Response**: - 如果有响应内容,查看是什么 - 如果是HTML页面(ngrok警告页),说明需要点击"Visit Site"按钮 ### 步骤6:检查ngrok可能的拦截 ngrok免费版可能会: 1. **显示警告页面**:首次访问需要点击"Visit Site"按钮 2. **限制请求频率**:频繁请求可能被限流 3. **缓存响应**:可能返回缓存的响应而不是转发到后端 **解决方案**: - 在请求头中添加:`ngrok-skip-browser-warning: true` - 或者使用ngrok的付费版本 ### 步骤7:检查防火墙和网络 ```bash # Windows防火墙可能阻止了8080端口 # 检查Windows防火墙设置,确保8080端口允许入站连接 ``` ## 常见问题及解决方案 ### 问题1:完全没有日志输出 **可能原因**: - ngrok没有正确转发请求 - 后端应用没有启动 - 防火墙阻止了连接 - ngrok配置错误 **解决方案**: 1. 确认后端应用正在运行(步骤1) 2. 确认ngrok配置正确(步骤3) 3. 测试本地接口(步骤2) 4. 检查防火墙设置 ### 问题2:看到Filter日志,但没有拦截器日志 **可能原因**: - 请求路径不匹配拦截器配置 - 请求被其他Filter拦截并返回 **解决方案**: - 检查请求URI是否匹配 `/wechat/**` 模式 - 检查是否有其他Filter或配置阻止了请求 ### 问题3:看到拦截器日志,但返回401 **可能原因**: - Token不存在或格式错误 - Token已过期 - Token验证失败 **解决方案**: - 检查请求头中的 `Authorization` 值 - 确认Token格式:`HDU xxxxxx`(注意有空格) - 重新登录获取新Token ### 问题4:ngrok显示502 Bad Gateway **可能原因**: - 后端应用没有运行 - ngrok无法连接到localhost:8080 - 端口被占用 **解决方案**: - 确认后端应用正在运行 - 尝试使用 `127.0.0.1:8080` 而不是 `localhost:8080` - 检查端口是否被占用 ## 下一步操作 1. **重启后端服务**,查看新增的日志输出 2. **执行步骤1-7的诊断**,记录结果 3. **根据日志输出判断问题位置**: - 没有Filter日志 → ngrok或网络问题 - 有Filter日志但没有拦截器日志 → 路径匹配问题 - 有拦截器日志但401 → Token问题 - 有拦截器日志且通过 → 检查Controller和业务逻辑 ## 联系信息 如果问题仍未解决,请提供: 1. **后端完整日志**(从启动到请求的完整日志) 2. **ngrok Traffic Inspector截图**(请求详情页面) 3. **前端请求代码**(特别是URL和请求头设置) 4. **步骤1-7的诊断结果**