dgrijalva / jwt-go

ARCHIVE - Golang implementation of JSON Web Tokens (JWT). This project is now maintained at:
https://github.com/golang-jwt/jwt
MIT License
10.78k stars 994 forks source link

invalid signature error #435

Closed fvisconti closed 3 years ago

fvisconti commented 3 years ago

Hi there,

I'm using your software with go1.13.7.

I'm trying to generate a token with SigningMethodHS256 and pass it through the header to the client. Then I verify the signature and token validity in a successive call to an endpoint, but I get signature is invalid error text, even if the error is not of the type jwt.ErrSignatureInvalid.

Here's the code, maybe there's some macroscopic error I cannot see.

var jwtKey = []byte("SECRET")

type Claims struct {
    Username string `json:"username"`
    jwt.StandardClaims
}

func lookForBearer(header string) (token string, err error) {
    splheader := strings.Split(header, " ")
    if strings.ToLower(splheader[0]) != "bearer" {
        return "", fmt.Errorf("Not authorized scheme, missing bearer")
    }
    return splheader[1], nil
}

// SetJWT ...
func SetJWT(c *gin.Context, username string) {
    expirationTime := time.Now().Add(5 * time.Hour).Local().Unix()

    claims := &Claims{
        Username: username,
        StandardClaims: jwt.StandardClaims{
            // In JWT, the expiry time is expressed as unix milliseconds
            ExpiresAt: expirationTime,
        },
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    tokenString, err := token.SignedString(jwtKey)

    if err != nil {
        c.Writer.WriteHeader(http.StatusInternalServerError)
        return
    }

    c.Writer.Header().Set("token", tokenString)
}

// Welcome ...
func Welcome(c *gin.Context) {
    jwtString := c.GetHeader("Authorization")
    log.Infof("token taken from Header: %s", jwtString)

    tokenString, err := lookForBearer(jwtString)
    if err != nil {
        log.Errorln(err)
        c.Writer.WriteHeader(http.StatusBadRequest)
        return
    }

    claims := &Claims{}

    token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
        return jwtKey, nil
    })

    if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
        log.Errorf("Unexpected signing method: %v", token.Header["alg"])
        c.Writer.WriteHeader(http.StatusBadRequest)
        return
    }

    if err != nil {
        if err == jwt.ErrSignatureInvalid {
            log.Errorln("SIGNATURE ERROR")
            c.Writer.WriteHeader(http.StatusUnauthorized)
            return
        }
        log.Errorln("OTHER ERROR")
        log.Errorln(err)
        c.Writer.WriteHeader(http.StatusBadRequest)
        return
    }
    if !token.Valid {
        log.Errorln("Token not valid")
        c.Writer.WriteHeader(http.StatusUnauthorized)
        return
    }

    c.JSON(http.StatusOK, gin.H{
        "code":    http.StatusOK,
        "message": fmt.Sprintf("Welcome %s!", claims.Username),
    })
}

The SetJWT function is called after a traditional login with username and password.

When I call the Welcome endpoint via Postman with an Authorization Bearer Token set to the token I get from the SetJWT, I get the error:

{"level":"error","msg":"OTHER ERROR","time":"2020-10-20T15:51:15+02:00"}
{"level":"error","msg":"signature is invalid","time":"2020-10-20T15:51:15+02:00"}
[GIN] 2020/10/20 - 15:51:15 | 400 |     255.314µs |             ::1 | GET      "/welcome"

Many thanks in advance.

fvisconti commented 3 years ago

It just works, I was passing the wrong token. Shame on me :(