psbits
psbits

Reputation: 1897

Using jwt-go Library - Key is invalid or invalid type

I am trying to pass in a token to the "Parse(token String, keyFunc Keyfunc)" GO routine defined in this GO-library (http://godoc.org/github.com/dgrijalva/jwt-go) for JWT-token parsing/validation.

When I pass the token to this function -

token, err := jwt.Parse(getToken, func(token *jwt.Token) (interface{}, error) {
        return config.Config.Key, nil
    })

I get an error which says "Key is invalid or invalid type".

My config struct looks like this in config.go file -

config struct {
 Key string
}

Any suggestions to solve this problem? The token I am passing is a JWT token.

Upvotes: 10

Views: 18224

Answers (5)

venkat7668
venkat7668

Reputation: 2767

This is working for me.

token.SignedString([]byte("mysecretkey"))

func GenerateJWT(email string, username string) (tokenString string, err error) {

    expirationTime := time.Now().Add(1 * time.Hour)
    claims := &JWTClime{
        Email:    email,
        Username: username,
        StandardClaims: jwt.StandardClaims{
            ExpiresAt: expirationTime.Unix(),
        },
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    tokenString, err = token.SignedString([]byte("mysecretkey"))

    return
}

Upvotes: 3

Mandeep Gill
Mandeep Gill

Reputation: 4885

I am not sure if this can be an issue for someone else.

My problem was I was using Signing Method "SigningMethodES256" but "SigningMethodHS256" or Any with SigningMethodHS* works fine.

If someone knows why this is an issue please answer.

Upvotes: 19

Niko
Niko

Reputation: 697

Taking a look at the function signatures in the GoDoc for github.com/dgrijalva/jwt-go we see:

func Parse(tokenString string, keyFunc Keyfunc) (*Token, error)

type Keyfunc func(*Token) (interface{}, error)

Keyfunc requires you to return (interface{}, error). Given the mysterious interface{} type, you might expect to be fine returning a string; however, a peek under the hood reveals that Parse() tries to Verify(), which attempts the following type assertion with your interface{} value as the key:

keyBytes, ok := key.([]byte)

That will succeed for []byte types, but will fail for string types. When that fails, the result is the error message you are getting. Read more about type assertions in the Effective Go documentation to learn why it fails.

Example: https://play.golang.org/p/9KKNFLLQrm

package main

import "fmt"

func main() {
    var a interface{}
    var b interface{}

    a = []byte("hello")
    b = "hello"

    key, ok := a.([]byte)
    if !ok {
        fmt.Println("a is an invalid type")
    } else {
        fmt.Println(key)
    }

    key, ok = b.([]byte)
    if !ok {
        fmt.Println("b is an invalid type")
    } else {
        fmt.Println(key)
    }
}

[104 101 108 108 111]
b is an invalid type

Upvotes: 1

psbits
psbits

Reputation: 1897

Other way is to do something like this -

token, err := jwt.Parse(getToken, func(token *jwt.Token) (interface{}, error) {
        return []byte(config.Config.Key), nil
    })

The whole idea being that the Parse function returns a slice of bytes.

Upvotes: 6

Jesse
Jesse

Reputation: 246

config struct {
 Key string
}

Key needs to be a []byte

Upvotes: 23

Related Questions