package token import ( "errors" "fmt" "time" "github.com/dgrijalva/jwt-go" ) const minSecretKeySize = 32 type JWTMaker struct { secretKey string } func NewJWTMaker(secretKey string) (Maker, error) { if len(secretKey) < minSecretKeySize { return nil, fmt.Errorf("Invalid key: must be at least %d characters", minSecretKeySize) } return &JWTMaker{secretKey}, nil } func (maker *JWTMaker) CreateToken(email string, duration time.Duration) (string, error) { payload, err := NewPayload(email, duration) if err != nil { return "", err } jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, payload) return jwtToken.SignedString([]byte(maker.secretKey)) } func (maker *JWTMaker) VerifyToken(token string) (*Payload, error) { keyFunc := func(token *jwt.Token) (interface{}, error) { _, ok := token.Method.(*jwt.SigningMethodHMAC) if !ok { return nil, ErrInvalidToken } return []byte(maker.secretKey), nil } jwtToken, err := jwt.ParseWithClaims(token, &Payload{}, keyFunc) if err != nil { verr, ok := err.(*jwt.ValidationError) if ok && errors.Is(verr.Inner, ErrExpiredToken) { return nil, ErrExpiredToken } return nil, ErrInvalidToken } payload, ok := jwtToken.Claims.(*Payload) if !ok { return nil, ErrInvalidToken } return payload, nil }