package middleware import ( "encoding/json" "fmt" "hpds-iot-web/model" e "hpds-iot-web/pkg/err" "net/http" "time" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt" "go.uber.org/zap" ) var secretKey = []byte("17715d3df8712f0a3b31cfed384f668e95822de4e4a371e4ceaa6f1b279e482a0af32b4615d39f8857d0a1d99d2787f773147a9ed7587b243e0fe1b04076e307") // 验签使用 var AuthKey = "auth-key" var AuthSignature = "auth-signature" // Claims 自定义声明 type Claims struct { Avatar string `json:"avatar"` Desc string `json:"desc"` HomePath string `json:"homePath"` RealName string `json:"realName"` Roles []model.SystemRole `json:"roles"` UserId int64 `json:"userId"` Token string `json:"token,omitempty"` Phone string `json:"phone"` jwt.StandardClaims } // Sign 生成token func Sign(user *model.SystemUser, expires int) (string, error) { // 过期时间为秒 expAt := time.Now().Add(time.Duration(expires) * time.Second).Unix() // 创建声明 claims := Claims{ Avatar: user.Avatar, Desc: user.Desc, HomePath: user.HomePath, RealName: user.RealName, Roles: model.GetRolesByUserId(user.UserId), UserId: user.UserId, Phone: user.Phone, StandardClaims: jwt.StandardClaims{ ExpiresAt: expAt, Issuer: "交科院", }, } var err error //创建token,指定加密算法为HS256 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) claims.Token, err = token.SignedString(secretKey) //生成token return claims.Token, err } // JwtAuthMiddleware JWT处理中间件 func JwtAuthMiddleware(logger *zap.Logger) gin.HandlerFunc { return func(c *gin.Context) { path := c.Request.URL.Path var ( err error Cookie *http.Cookie usClaims *Claims user *model.SystemUser ) token := c.GetHeader("Authorization") // 这里可以过滤不需要进行验证的接口 if path == "/api/user/login" || path == "/api/health" || path == "/api/task/event" { goto Return } if len(token) == 0 { Cookie, err = c.Request.Cookie("token") if err != nil { logger.With( zap.String("method", c.Request.Method), zap.String("path", path), zap.Any("request", c.Params), ).Error(err.Error()) goto Return } token = Cookie.Value } if len(token) <= 0 { logger.With( zap.String("method", c.Request.Method), zap.String("path", path), zap.Any("request", c.Params), ).Error("缺少token") goto Return } usClaims, err = GetUserInfoByToken(c, token, logger) if err != nil { c.JSON(e.NoAuth, gin.H{"code": e.NoAuth, "msg": "未登录的用户请求"}) c.Abort() return } if err != nil { logger.With( zap.String("method", c.Request.Method), zap.String("path", path), zap.Any("request", c.Params), ).Error(err.Error()) goto Return } user, err = model.GetUserById(usClaims.UserId) if err != nil { logger.With( zap.String("method", c.Request.Method), zap.String("path", path), zap.Any("request", c.Params), ).Error(err.Error()) goto Return } c.Set("operatorUser", user) Return: if err != nil { c.Header("Content-Type", "application/json") c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ "code": http.StatusBadRequest, "status": http.StatusText(http.StatusBadRequest), "path": path, "message": "失败", "error": "token过期/失效,请登录后重试", "data": nil, }) return } c.Next() } } func GetUserInfoByToken(ctx *gin.Context, token string, logger *zap.Logger) (data *Claims, err error) { nosql := NewNoSql(logger) su, err := nosql.Get(ctx, token) if err != nil { return nil, err } data = new(Claims) err = json.Unmarshal([]byte(fmt.Sprintf("%s", su)), data) if err != nil { return nil, err } return data, nil }