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 997 forks source link

Issue: ParseWithClaims() cannot unmarshal number into Go struct field Claims.sub of type string #446

Open DangerosoDavo opened 3 years ago

DangerosoDavo commented 3 years ago

Issue: ParseWithClaims() cannot unmarshal number into Go struct field Claims.sub of type string

I'm trying to parse claims ill show the code I'm attempting:

// ResponseEnum ...
type ResponseEnum int32

const (
    // RespSuccess - A Successful Response to auth.
    RespSuccess ResponseEnum = iota
    // RespErrCreds - A problem with the provided Credientials.
    RespErrCreds
    // RespErrUnAuthorised - A problem authorising the given Credentials.
    RespErrUnAuthorised
    // RespErrToken - A problem with the provided token.
    RespErrToken
    // RespErrBadRequest - The request was malformed.
    RespErrBadRequest
)

func (r ResponseEnum) String() string {
    return [...]string{"Success", "Error Credentials", "Error Unauthorised", "Error Failed Token", "Error failed auth request"}[r]
}

// Create the JWT key used to create the signature
var jwtKey = []byte("some sig") // actually a valid sig but edited here.

// Credentials ...
type Credentials struct {
    Token string `json:"token"`
}

// Claims ...
type Claims struct {
    User struct {
        ID       int    `json:"id"`
        UserType int    `json:"user_type"`
        Email    string `json:"email"`
    } `json:"user"`
    jwt.StandardClaims
}

// JWTAuth ...
type JWTAuth struct {
}

// Signin ...
func (JWTAuth) Signin(authStr *string) (ResponseEnum, *server.Account, error) {
    log.Println("Auth::Signin")
    claims := &Claims{}

    tkn, err := jwt.ParseWithClaims(*authStr, claims, func(token *jwt.Token) (interface{}, error) {
        return jwtKey, nil
    })
    log.Println("Auth::ParseWithClaims", tkn, err)

    log.Printf("Auth:: Token Valid: %+v", tkn.Valid)

    if err != nil {
        if err == jwt.ErrSignatureInvalid {
            log.Println(RespErrUnAuthorised.String())
        }
        log.Println(RespErrBadRequest.String())
        return RespErrBadRequest, nil, errors.New(RespErrBadRequest.String())
    }

    if !tkn.Valid {
        log.Println(RespErrUnAuthorised.String())
        return RespErrUnAuthorised, nil, errors.New(RespErrUnAuthorised.String())
    }
    // Auth success, this is the correct person.
    log.Println("Auth::Token Validated.")
    return RespSuccess, &server.Account{ID: claims.User.ID, Email: claims.User.Email, UserType: claims.User.UserType}, nil
}

The token has this in the payload "user":{"id":1,"user_type":1,"email":"a valid email"}

the output to console is: {{TOKEN STRING}} json: cannot unmarshal number into Go struct field Claims.sub of type string 2021/01/19 18:07:33 Auth:: Token Valid: false

Im not sure the issue is with the implementation but I'm at an impasse on how to continue and I believe the reason its not valid is to do with that json unmarshal error. Any ideas on how to fix this?

softwarespot commented 3 years ago

See https://github.com/dgrijalva/jwt-go/issues/454