package utils import ( "fmt" "github.com/beego/beego/v2/server/web/context" ) // AuthMiddleware Token认证中间件 func AuthMiddleware(ctx *context.Context) { // ============ 最优先:立即打印,证明中间件被调用 ============ fmt.Printf("\n\n🚀🚀🚀🚀🚀 [AUTH中间件] 开始执行!\n") fmt.Printf(" 请求方法: %s\n", ctx.Request.Method) fmt.Printf(" 请求路径: %s\n", ctx.Request.URL.Path) fmt.Printf(" 完整URL: %s\n", ctx.Request.URL.String()) // 添加一个 defer 来捕获任何 panic defer func() { if r := recover(); r != nil { fmt.Printf("❌❌❌ [中间件] 发生panic: %v\n", r) } }() // 跳过某些不需要认证的路由 skipPaths := []string{ "/stream-test", "/simple-stream-test", "/stream-chat-with-db-test", "/assets/", "/static/", "/src/", "/apiv1/oss/parse", // OSS代理解析接口,用于图片/文件资源访问,不需要token认证 } // 特殊处理:精确匹配根路径 "/" if ctx.Request.URL.Path == "/" { fmt.Printf("⏭️ [中间件] 跳过路径: / (根路径)\n\n") return } // 检查其他跳过路径 for _, path := range skipPaths { // 精确匹配或前缀匹配(对于目录路径) if ctx.Request.URL.Path == path || (len(ctx.Request.URL.Path) > len(path) && ctx.Request.URL.Path[:len(path)] == path) { fmt.Printf("⏭️ [中间件] 跳过路径: %s (匹配规则: %s)\n\n", ctx.Request.URL.Path, path) return } } // 对于API请求,验证token if len(ctx.Request.URL.Path) >= 6 && ctx.Request.URL.Path[:6] == "/apiv1" { // 打印所有请求头,帮助调试 fmt.Printf("\n========== Token认证中间件 ==========\n") fmt.Printf("📍 请求路径: %s\n", ctx.Request.URL.Path) fmt.Printf("📋 所有请求头:\n") for key, values := range ctx.Request.Header { fmt.Printf(" %s: %v\n", key, values) } // 获取token - 添加详细的调试信息 fmt.Printf("\n🔍 开始提取Token:\n") token1 := ctx.Input.Header("token") fmt.Printf(" 尝试 'token': %s (长度: %d)\n", token1, len(token1)) token2 := ctx.Input.Header("Token") fmt.Printf(" 尝试 'Token': %s (长度: %d)\n", token2, len(token2)) token3 := ctx.Input.Header("Authorization") fmt.Printf(" 尝试 'Authorization': %s (长度: %d)\n", token3, len(token3)) // 确定最终使用的token token := token1 if token == "" { token = token2 } if token == "" { token = token3 // 如果是Bearer token格式,去掉"Bearer "前缀 if len(token) > 7 && token[:7] == "Bearer " { oldToken := token token = token[7:] fmt.Printf(" 去除Bearer前缀: %s -> %s\n", oldToken[:20]+"...", token[:20]+"...") } } fmt.Printf("\n🔑 最终提取到的Token: %s (长度: %d)\n", token, len(token)) // 如果没有token,返回401 if token == "" { fmt.Printf("❌❌❌ Token为空,拒绝请求\n") fmt.Printf("❌ 原因:请求头中没有找到 token、Token 或 Authorization 字段\n") fmt.Printf("=====================================\n\n") ctx.Output.SetStatus(401) ctx.Output.JSON(map[string]interface{}{ "statusCode": 401, "msg": "未提供认证token,请在请求头中添加 token 字段", }, false, false) return } // 验证token userInfo, err := VerifyToken(token) if err != nil { fmt.Printf("❌❌❌ Token验证失败: %v\n", err) fmt.Printf("❌ Token内容: %s\n", token) fmt.Printf("❌ 请检查token是否正确或已过期\n") fmt.Printf("=====================================\n\n") ctx.Output.SetStatus(401) ctx.Output.JSON(map[string]interface{}{ "statusCode": 401, "msg": fmt.Sprintf("token验证失败: %v", err), }, false, false) return } // 打印解析出的用户信息 fmt.Printf("✅ Token验证成功,解析出的用户信息:\n") fmt.Printf(" - AccountID: %s\n", userInfo.AccountID) fmt.Printf(" - ID: %d\n", userInfo.ID) fmt.Printf(" - Name: %s\n", userInfo.Name) fmt.Printf(" - UserCode: %s\n", userInfo.UserCode) fmt.Printf(" - ContactNumber: %s\n", userInfo.ContactNumber) fmt.Printf(" - TokenType: %s\n", userInfo.TokenType) // 将用户信息存储到context中,供后续handler使用 fmt.Printf("\n💾 [中间件] 将用户信息存储到context中...\n") fmt.Printf(" 存储的指针地址: %p\n", userInfo) fmt.Printf(" 存储的值: %+v\n", userInfo) ctx.Input.SetData("userInfo", userInfo) // 验证是否存储成功 storedData := ctx.Input.GetData("userInfo") fmt.Printf(" 验证存储: %T, 值=%+v\n", storedData, storedData) fmt.Printf("=====================================\n\n") } else { fmt.Printf("⏭️ [中间件] 非API路径,不需要token验证: %s\n\n", ctx.Request.URL.Path) } }