Learning Go as I work through creating a REST API. Getting the error undefined: authDetails
when I use it the two times at the bottom to access the fields. I understand that it's set in a branch that may not be executed. I've tried moving it outside of the branch, or declaring it above with var authDetails auth.AccessDetails
and then setting the values afterwards. I've also tried moving the assignment outside of the braces, but no matter what I do it doesn't seem to carry the values from within the conditional block out to where I try to use them.
I think I'm misunderstanding something regarding scope, if someone could assist me in understanding what the problem is it would be a huge help.
The Struct definition is:
type AccessDetails struct {
AccessUuid string
UserId uint64
}
and the code is:
func (server *Server) GetTokenUserIDFromRequest(r *http.Request) (uint64, error) {
var authDetails auth.AccessDetails
tokenString := auth.ExtractToken(r)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return 0, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return []byte(os.Getenv("API_SECRET")), nil
})
if err != nil {
return 0, err
}
claims, ok := token.Claims.(jwt.MapClaims)
if ok && token.Valid {
accessUuid, ok := claims["access_uuid"].(string)
if !ok {
return 0, errors.New("token not valid, cannot retrieve access_uuid")
}
userid, err := strconv.ParseUint(fmt.Sprintf("%.0f", claims["user_id"]), 10, 64)
if err != nil {
return 0, err
}
authDetails := &auth.AccessDetails{
AccessUuid: accessUuid,
UserId: userid,
}
}
redisuserid, err := server.RedisClient.Get(authDetails.AccessUuid).Result()
if err != nil {
return 0, err
}
userID, _ := strconv.ParseUint(redisuserid, 10, 64)
if userID != authDetails.UserId {
return 0, errors.New("userid from token does not match userid from database")
}
return userID, nil
}
You are redeclaring authDetails
in the if
-block instead of setting the value declared at the outer scope. The relevant section in the language specification is:
https://golang.org/ref/spec#Short_variable_declarations
Instead of authDetails:=...
use authDetails=...
, so it becomes an assignment, not a declaration.