You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.8 KiB
72 lines
2.8 KiB
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
|
|
}
|
|
|