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

Can explain me why uses pointers to type assertion otherwhise error? #442

Closed josegoval closed 2 years ago

josegoval commented 3 years ago

Hello there. I haave this code:

func ValidateToken(signedToken string) {
    token, err := jwt.ParseWithClaims(signedToken, &CustomTokenClaims{}, func(t *jwt.Token) (interface{}, error) { return mySecretKey, nil })
    if err != nil {
        if errorType, ok := err.(*jwt.ValidationError); ok {
            if errorType.Errors == jwt.ValidationErrorExpired {
                panic("Time Expired!")
            }
        }
        panic(err)
    }

    if claims, ok := token.Claims.(*CustomTokenClaims); ok && token.Valid {
        fmt.Println(claims.SessionID)
    } else {
        fmt.Println(claims)
        fmt.Println(ok, token.Valid)
    }
}

but i dont understand why do I have to use jwt.ValidationError and CustomTokenClaims instead of normal value, as well as why "ParseWithClaims" recieves a reference of "CustomTokenClaims".

Thank you.

EvgeniiPoshvin commented 3 years ago

1) Why *jwt.ValidationError

Actually what jwt.ParseWithClaims returns in case of an error is a pointer to jwt.ValidationError (e.g. one of the place we return error https://github.com/dgrijalva/jwt-go/blob/master/parser.go#L41)

The ValidationError itself is a structure that implements the error interface or simply speaking has Error method implemented so that satisfy the error interface (https://github.com/dgrijalva/jwt-go/blob/master/errors.go#L39)

Also, take a look at some boilerplate code, let's say best practice, here https://blog.golang.org/go1.13-errors, hope at helps.

josegoval commented 3 years ago

(Maybe i mess it a bit, am new using this system)

Thank you a lot, seriously, A LOT. This make it quite clear.

So, the reason because the claims assertion requires a pointer to CustomTokenClaims, is because, it is an interface, and it needs to be a pointer to use all the interface methods that StandardClaims has, like func (c *StandardClaims) VerifyAudience(cmp string, req bool)?

Thanks again.