gojwtgolang-jwt

go-jwt token validation error - token signature is invalid: key is of invalid type


Getting an error

token signature is invalid: key is of invalid type

When trying to validate JWT token. Using golang-jwt (v5) library.

Here is how I'm generating a token:

const (
    secretKey     = "162475e134198bd451af0b88a5defe132c72cb26fd58449772883b90c498b484"
    tokenLifespan = 4
)

func GenerateToken() (string, error) {
    claims := jwt.MapClaims{}
    claims["authorized"] = true
    claims["foo"] = "bar"
    claims["exp"] = time.Now().Add(time.Hour * time.Duration(tokenLifespan)).Unix()
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

    return token.SignedString([]byte(secretKey))
}

Here is the generated token: jwt token decoded

And here is how I'm validating the token:

func ValidateToken(c *gin.Context) error {
    token, err := GetToken(c)

    if err != nil {
        return err
    }

    _, ok := token.Claims.(jwt.MapClaims)
    if ok && token.Valid {
        return nil
    }

    return errors.New("invalid token provided")
}

func GetToken(c *gin.Context) (*jwt.Token, error) {
    tokenString := getTokenFromRequest(c)
    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
            return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
        }

        return token, nil
    })
    return token, err
}

func getTokenFromRequest(c *gin.Context) string {
    bearerToken := c.Request.Header.Get("Authorization")

    splitToken := strings.Split(bearerToken, " ")
    if len(splitToken) == 2 {
        return splitToken[1]
    }
    return ""
}

Any suggestions how to get it working? What am I missing? Thanks.


Solution

  • The Keyfunc is used by the Parse methods as a callback function to supply the key for verification. So it should return a key instead of the parameter token *jwt.Token.

      token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
            return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
        }
    
    -   return token, nil
    +   return []byte(secretKey), nil
      })