package console import ( "net/http" "yunyan/comm" "yunyan/pb" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v4" ) // cors 允许跨域(控制面前端可能与服务不同源)。 func cors() gin.HandlerFunc { return func(c *gin.Context) { c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-App-Id") c.Header("Access-Control-Expose-Headers", "Content-Length, Content-Type") if c.Request.Method == http.MethodOptions { c.AbortWithStatus(http.StatusNoContent) return } c.Next() } } // writeResult 统一返回 comm.HttpResult,与现有 console 前端约定一致(code==0 成功,code==18 未登录)。 func writeResult(c *gin.Context, code pb.ErrorCode, msg string, data interface{}) { c.JSON(http.StatusOK, &comm.HttpResult{Code: code, Message: msg, Data: data}) } func writeOK(c *gin.Context, data interface{}) { writeResult(c, pb.ErrorCode_Success, "Success", data) } func writeErr(c *gin.Context, code pb.ErrorCode, msg string) { writeResult(c, code, msg, nil) } // consoleClaims 后台 JWT 声明:在标准声明之上带角色、用户名、账号 id,供鉴权中间件按角色控权。 type consoleClaims struct { Identity pb.Identity `json:"idt"` // 角色:1超管 2管理员 3代理商(品牌商) 4运营 5渠道商 Username string `json:"usr"` AccountId uint32 `json:"aid"` // 账号表 id;引导超管为 0 // 数据作用域绑定(代理/运营才有;超管/管理员为空=不受限)。随 token 下发,每个请求据此强制隔离, // 避免每请求回查海外账号库。CSV 格式,与 Account.Apps/Products/Regions 一致。 Apps string `json:"aps,omitempty"` // 绑定应用名列表 Products string `json:"prd,omitempty"` // 绑定产品 id 列表 Regions string `json:"rgn,omitempty"` // 绑定区域代码列表 // 渠道分成体系的归属绑定:品牌商账号(3)只有 Brandid;渠道商账号(5)两者都有。 Brandid uint32 `json:"bid,omitempty"` // 绑定品牌商 id Channelid string `json:"cid,omitempty"` // 绑定渠道商 id(短码) jwt.RegisteredClaims } // parseToken 校验 JWT 并返回声明。与签发口径一致(HS256 + TokenKey)。 func parseToken(tokenString string, secretKey []byte) (*consoleClaims, error) { parsed, err := jwt.ParseWithClaims(tokenString, &consoleClaims{}, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, jwt.ErrSignatureInvalid } return secretKey, nil }) if err != nil { return nil, err } if claims, ok := parsed.Claims.(*consoleClaims); ok && parsed.Valid { return claims, nil } return nil, jwt.ErrTokenInvalidClaims }