Using jwt-go Library - Key is invalid or invalid type
Asked Answered
R

5

10

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.

Receptor answered 28/1, 2015 at 23:28 Comment(0)
G
22
config struct {
 Key string
}

Key needs to be a []byte

Glorify answered 4/2, 2015 at 16:27 Comment(2)
While this code sample may possibly answer the question, it would be preferable to include some essential explanation to your answer. As it stands now this answer adds little to no value for future readers.Sinistral
How to implement this exactly? Earlier I tried using []byte("key") without any struct and it gave me the error. A little elaboration to the solution might be helpful for newcomers @GlorifyAffecting
A
18

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.

Askew answered 22/8, 2021 at 14:16 Comment(2)
A bit late. It's because each signing method has its own key type. You can see the type expected for every signing method here golang-jwt.github.io/jwt/usage/signing_methodsLucillelucina
Yes thanks, but few people getting this issue.Askew
R
6

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.

Receptor answered 5/2, 2015 at 17:52 Comment(0)
R
3

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
}
Rhodie answered 5/10, 2022 at 7:52 Comment(0)
I
1

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
Iodoform answered 26/5, 2016 at 16:58 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.