package adminauth import ( "errors" "time" "github.com/golang-jwt/jwt/v5" ) var ( ErrTokenExpired = errors.New("token expired") ErrTokenMalformed = errors.New("token malformed") ErrTokenSignatureInvalid = errors.New("token signature invalid") ErrTokenNotValidYet = errors.New("token not valid yet") ErrTokenInvalid = errors.New("token invalid") ) type Claims struct { UUID string ID uint Username string NickName string AuthorityID uint `json:"AuthorityId"` BufferTime int64 MustChangePwd bool `json:"mustChangePwd"` jwt.RegisteredClaims } func Generate(secret, issuer string, expires, buffer time.Duration, userID, authorityID uint, uuid, username, nickname string, mustChange bool) (string, *Claims, error) { if secret == "" { return "", nil, errors.New("empty JWT signing key") } now := time.Now() claims := &Claims{UUID: uuid, ID: userID, Username: username, NickName: nickname, AuthorityID: authorityID, BufferTime: int64(buffer / time.Second), MustChangePwd: mustChange, RegisteredClaims: jwt.RegisteredClaims{Issuer: issuer, IssuedAt: jwt.NewNumericDate(now), NotBefore: jwt.NewNumericDate(now.Add(-time.Second)), ExpiresAt: jwt.NewNumericDate(now.Add(expires))}} token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(secret)) return token, claims, err } func Parse(tokenString, secret string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (any, error) { if token.Method != jwt.SigningMethodHS256 { return nil, errors.New("unexpected signing method") } return []byte(secret), nil }) if err != nil { switch { case errors.Is(err, jwt.ErrTokenExpired): return nil, ErrTokenExpired case errors.Is(err, jwt.ErrTokenMalformed): return nil, ErrTokenMalformed case errors.Is(err, jwt.ErrTokenSignatureInvalid): return nil, ErrTokenSignatureInvalid case errors.Is(err, jwt.ErrTokenNotValidYet): return nil, ErrTokenNotValidYet default: return nil, ErrTokenInvalid } } if !token.Valid { return nil, ErrTokenInvalid } claims, ok := token.Claims.(*Claims) if !ok { return nil, errors.New("token claims are invalid") } return claims, nil }