Having some trouble validating jwt tokens using golang-jwt. Pretty sure I’m forming the tokens properly because I’m able to print them and they’re being return fine, however when I try to parse them and extract the claims I’m getting an error saying signature is invalid.
I’m using the echo framework for my API, in case that matters.
This is my authentication middleware func
func validateJWT(tokenString string) (*jwt.Token, error) {
settings := functions.GetSettings(global.SETTINGS_FILE)
secretKey := settings.Secretkey
return jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
return []byte(secretKey), nil
})
}
func Authenticator(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// Get the token from the header
tokenString := strings.Split(c.Request().Header.Get("Authorization"), "Bearer ")[1]
token, err := validateJWT(tokenString)
if err != nil {
fmt.Println(err)
return c.JSON(401, map[string]interface{}{
"error": "Invalid token",
})
}
if !token.Valid {
return c.JSON(401, map[string]interface{}{
"error": "Invalid token",
})
}
claims := token.Claims.(jwt.MapClaims)
// Set the user in the context
c.Set("user", claims["username"])
return next(c)
}
}
This is my token creation
func createToken(secretKey string, username string) (string, error) {
claim := jwt.MapClaims{
"username": username,
"exp": time.Now().Add(time.Hour * 24).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)
tokenString, err := token.SignedString([]byte(secretKey))
if err != nil {
return "", err
}
return tokenString, nil
}
func sendToken(c echo.Context, secretKey string, username string) error {
token, err := createToken(secretKey, username)
if err != nil {
return c.String(500, "Internal Server Error")
}
return c.String(200, token)
}
// login
func RouteLogin(c echo.Context) error {
settings := functions.GetSettings(global.SETTINGS_FILE)
secretKey := string([]byte(settings.Secretkey))
username := c.FormValue("username")
password := c.FormValue("password")
// if username is not admin get all guest account info
if username == "admin" {
if password != settings.Accounts.Admin.Password {
return c.String(401, "Unauthorized")
} else {
sendToken(c, secretKey, username)
}
} else {
accounts := settings.Accounts.GuestAccounts
account, ok := accounts[username]
if !ok {
return c.String(404, "Not Found")
}
if account.Password != password {
return c.String(401, "Unauthorized")
}
sendToken(c, secretKey, username)
}
return c.String(200, "login")
}