func()

in auth/token_verifier.go [250:308]


func (tv *tokenVerifier) verifyHeaderAndBody(token string, isEmulator bool) (*Token, error) {
	var (
		header  jwtHeader
		payload Token
	)

	segments := strings.Split(token, ".")
	if len(segments) != 3 {
		return nil, errors.New("incorrect number of segments")
	}

	if err := decode(segments[0], &header); err != nil {
		return nil, err
	}

	if err := decode(segments[1], &payload); err != nil {
		return nil, err
	}

	issuer := tv.issuerPrefix + tv.projectID
	if !isEmulator && header.KeyID == "" {
		if payload.Audience == firebaseAudience {
			return nil, fmt.Errorf("expected %s but got a custom token", tv.articledShortName)
		}
		return nil, fmt.Errorf("%s has no 'kid' header", tv.shortName)
	}
	if !isEmulator && header.Algorithm != "RS256" {
		return nil, fmt.Errorf("%s has invalid algorithm; expected 'RS256' but got %q",
			tv.shortName, header.Algorithm)
	}
	if payload.Audience != tv.projectID {
		return nil, fmt.Errorf("%s has invalid 'aud' (audience) claim; expected %q but got %q; %s",
			tv.shortName, tv.projectID, payload.Audience, tv.getProjectIDMatchMessage())
	}
	if payload.Issuer != issuer {
		return nil, fmt.Errorf("%s has invalid 'iss' (issuer) claim; expected %q but got %q; %s",
			tv.shortName, issuer, payload.Issuer, tv.getProjectIDMatchMessage())
	}
	if payload.Subject == "" {
		return nil, fmt.Errorf("%s has empty 'sub' (subject) claim", tv.shortName)
	}
	if len(payload.Subject) > 128 {
		return nil, fmt.Errorf("%s has a 'sub' (subject) claim longer than 128 characters",
			tv.shortName)
	}

	payload.UID = payload.Subject

	var customClaims map[string]interface{}
	if err := decode(segments[1], &customClaims); err != nil {
		return nil, err
	}
	for _, standardClaim := range []string{"iss", "aud", "exp", "iat", "sub", "uid"} {
		delete(customClaims, standardClaim)
	}
	payload.Claims = customClaims

	return &payload, nil
}