Invalid audience with Go API backend (Frontend: React SPA)

Getting an invalid audience when I try to connect to the API with the frontend. Have tried sending request with Postman, only works with the token that we get in the “test” section of our API dashboard. I’m guessing this is because of 2 audiences in the token. Running the backend on port 8000, I’m putting the relevant details below, please let me know if more is needed.
Token has:

{
      "iss": My_Domain,
      "aud": [
        "http://localhost:8000/",
        My_Domain,
      ],
}

In the backend:

aud := "http://localhost:8000/"
checkAud := token.Claims.(jwt.MapClaims).VerifyAudience(aud, false)
if !checkAud {
	return token, errors.New("Invalid audience.")
}

From the package (GitHub - auth0/go-jwt-middleware: A Middleware for Go Programming Language to check for JWTs on HTTP requests):

// Compares the aud claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
	aud, ok := m["aud"].([]string)
	if !ok {
		strAud, ok := m["aud"].(string)
		if !ok {
			return false
		}
		aud = append(aud, strAud)
	}

	return verifyAud(aud, cmp, req)
}

The verifyAud function:

func verifyAud(aud []string, cmp string, required bool) bool {
	if len(aud) == 0 {
		return !required
	}

	for _, a := range aud {
		if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 {
			return true
		}
	}
	return false
}

Looking at the functions, it seems that the multiple audiences shouldn’t be a problem, but apparently they are. Would greatly appreciate any help, thanks!

1 Like

Solved it.
The problem is here:

aud, ok := m[“aud”].(string)

This does not convert the slice, so it eventually returns false, thus giving “invalid audience”. I fixed it by adding my own code to the ValidationKeyGetter in the middleware.

aud := "http://localhost:8000/"

// convert audience in the JWT token to []interface{} if multiple audiences
convAud, ok := token.Claims.(jwt.MapClaims)["aud"].([]interface{})
if !ok {
	// convert audience in the JWT token to string if only 1 audience
	strAud, ok := token.Claims.(jwt.MapClaims)["aud"].(string)
	// return error if can't convert to string
	if !ok {
		return token, errors.New("Invalid audience.")
	}
	// return error if audience doesn't match
	if strAud != aud {
		return token, errors.New("Invalid audience.")
	}
} else {
	for _, v := range convAud {
		if v == aud {
		      break
		} else {
			return token, errors.New("Invalid audience.")
		}
	}
}

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.