package utils import ( "fmt" "strings" "github.com/beego/beego/v2/server/web/context" ) // 不需要认证的路径 var skipPaths = []string{ "/stream-test", "/simple-stream-test", "/stream-chat-with-db-test", "/assets/", "/static/", "/src/", "/apiv1/oss/parse", "/apiv1/auth/local_login", "/apiv1/recommend_question", } // AuthMiddleware Token认证中间件 func AuthMiddleware(ctx *context.Context) { path := ctx.Request.URL.Path // 跳过根路径 if path == "/" { return } // 检查跳过路径 for _, skip := range skipPaths { if path == skip || strings.HasPrefix(path, skip) { return } } // 仅对API请求验证token if !strings.HasPrefix(path, "/apiv1") { return } // 提取token token := extractToken(ctx) if token == "" { ctx.Output.SetStatus(401) ctx.Output.JSON(map[string]interface{}{ "statusCode": 401, "msg": "未提供认证token", }, false, false) return } // 优先验证本地token if localClaims, err := VerifyLocalToken(token); err == nil && localClaims != nil { ctx.Input.SetData("userInfo", ConvertLocalClaimsToTokenUserInfo(localClaims)) return } // 统一认证token验证 userInfo, err := VerifyToken(token) if err != nil { ctx.Output.SetStatus(401) ctx.Output.JSON(map[string]interface{}{ "statusCode": 401, "msg": fmt.Sprintf("token验证失败: %v", err), }, false, false) return } ctx.Input.SetData("userInfo", userInfo) } // extractToken 从请求头提取token func extractToken(ctx *context.Context) string { token := ctx.Input.Header("token") if token == "" { token = ctx.Input.Header("Token") } if token == "" { token = ctx.Input.Header("Authorization") if strings.HasPrefix(token, "Bearer ") { token = token[7:] } } return token }