package component import ( "context" "errors" "fmt" "gitee.ltd/lxh/logger/log" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" "strings" "time" "wireguard-dashboard/client" "wireguard-dashboard/config" "wireguard-dashboard/constant" ) const Secret = "IK8MSs76Pb2VJxleTDadf1Wzu3h9QROLv0XtmnCUErYgBG5wAyjk4cioqFZHNpZG" type JwtClaims struct { ID string `json:"id"` jwt.RegisteredClaims } func JWT() JwtClaims { return JwtClaims{} } // GenerateToken // @description: 生成token // @receiver Jwt // @return token // @return err func (j JwtClaims) GenerateToken(userId string) (token string, expireTime *jwt.NumericDate, err error) { timeNow := time.Now().Local() expireTime = jwt.NewNumericDate(timeNow.Add(7 * time.Hour)) notBefore := jwt.NewNumericDate(timeNow) issuedAt := jwt.NewNumericDate(timeNow) claims := JwtClaims{ ID: userId, RegisteredClaims: jwt.RegisteredClaims{ Issuer: config.Config.Http.Endpoint, // 颁发站点 Subject: "wg-dashboard", ExpiresAt: expireTime, NotBefore: notBefore, IssuedAt: issuedAt, ID: uuid.NewString(), }, } t := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) token, err = t.SignedString([]byte(Secret)) if err != nil { log.Errorf("生成token失败: %v", err.Error()) return "", nil, errors.New("生成token失败") } client.Redis.Set(context.Background(), fmt.Sprintf("%s:%s", constant.Token, userId), token, 7*time.Hour) return } // ParseToken // @description: 解析token // @receiver Jwt // @return Jwt // @return error func (JwtClaims) ParseToken(token string) (*JwtClaims, error) { tokenStr := strings.Split(token, "Bearer ")[1] t, err := jwt.ParseWithClaims(tokenStr, &JwtClaims{}, func(token *jwt.Token) (any, error) { return []byte(Secret), nil }) if claims, ok := t.Claims.(*JwtClaims); ok && t.Valid { userToken, err := client.Redis.Get(context.Background(), fmt.Sprintf("%s:%s", constant.Token, claims.ID)).Result() if err != nil { log.Errorf("缓存中用户[%s]的token查找失败: %v", claims.ID, err.Error()) return nil, errors.New("token不存在") } if userToken != tokenStr { log.Errorf("token不一致") return nil, errors.New("token错误") } return claims, nil } else { return nil, err } } // Logout // @description: 退出登陆 // @receiver JwtClaims // @param userId // @return err func (j JwtClaims) Logout(userId string) (err error) { return client.Redis.Del(context.Background(), fmt.Sprintf("%s:%s", constant.Token, userId)).Err() }