code: func VerifyIDToken(c context.Context, token string, keys *JSONWebKeySet, issuer, audience string) (*IDToken, error) {
  	// See https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken
  
  	body, err := keys.VerifyJWT(token)
  	if err != nil {
  		return nil, err
  	}
  	tok := &IDToken{}
  	if err := json.Unmarshal(body, tok); err != nil {
  		return nil, fmt.Errorf("bad ID token - not JSON - %s", err)
  	}
  
  	exp := time.Unix(tok.Exp, 0)
  	now := clock.Now(c)
  
  	switch {
  	case tok.Iss != issuer && "https://"+tok.Iss != issuer:
  		return nil, fmt.Errorf("bad ID token - expecting issuer %q, got %q", issuer, tok.Iss)
  	case tok.Aud != audience:
  		return nil, fmt.Errorf("bad ID token - expecting audience %q, got %q", audience, tok.Aud)
  	case !tok.EmailVerified:
  		return nil, fmt.Errorf("bad ID token - the email %q is not verified", tok.Email)
  	case tok.Sub == "":
  		return nil, fmt.Errorf("bad ID token - the subject is missing")
  	case exp.Add(allowedClockSkew).Before(now):
  		return nil, fmt.Errorf("bad ID token - expired %s ago", now.Sub(exp))
  	}
  
  	return tok, nil
  }
docs: // VerifyIDToken deserializes and verifies the ID token.
  //
  // This is a fast local operation.