def check_cached_certs(token, aud, cid)
      payload = nil

      # find first public key that validates this token
      @certs.detect do |key, cert|
        begin
          public_key = cert.public_key
          decoded_token = JWT.decode(token, public_key, !!public_key, { :algorithm => 'RS256' })
          payload = decoded_token.first

          # in Feb 2013, the 'cid' claim became the 'azp' claim per changes
          #  in the OIDC draft. At some future point we can go all-azp, but
          #  this should keep everything running for a while
          if payload['azp']
            payload['cid'] = payload['azp']
          elsif payload['cid']
            payload['azp'] = payload['cid']
          end
          payload
        rescue JWT::ExpiredSignature
          raise ExpiredTokenError, 'Token signature is expired'
        rescue JWT::DecodeError
          nil # go on, try the next cert
        end
      end

      if payload
        if !(payload.has_key?('aud') && payload['aud'] == aud)
          raise AudienceMismatchError, 'Token audience mismatch'
        end
        if cid && payload['cid'] != cid
          raise ClientIDMismatchError, 'Token client-id mismatch'
        end
        if !GOOGLE_ISSUERS.include?(payload['iss'])
          raise InvalidIssuerError, 'Token issuer mismatch'
        end
        payload
      else
        nil
      end
    end
def check_cached_certs(token, aud, cid)
      payload = nil

      # find first public key that validates this token
      @certs.detect do |key, cert|
        begin
          public_key = cert.public_key
          decoded_token = JWT.decode(token, public_key, !!public_key, { :algorithm => 'RS256' })
          payload = decoded_token.first

          # in Feb 2013, the 'cid' claim became the 'azp' claim per changes
          #  in the OIDC draft. At some future point we can go all-azp, but
          #  this should keep everything running for a while
          if payload['azp']
            payload['cid'] = payload['azp']
          elsif payload['cid']
            payload['azp'] = payload['cid']
          end
          payload
        rescue JWT::ExpiredSignature
          raise ExpiredTokenError, 'Token signature is expired'
        rescue JWT::DecodeError
          nil # go on, try the next cert
        end
      end

      if payload
        if !(payload.has_key?('aud') && payload['aud'] == aud)
          raise AudienceMismatchError, 'Token audience mismatch'
        end
        if cid && payload['cid'] != cid
          raise ClientIDMismatchError, 'Token client-id mismatch'
        end
        if !GOOGLE_ISSUERS.include?(payload['iss'])
          raise InvalidIssuerError, 'Token issuer mismatch'
        end
        payload
      else
        nil
      end
    end
tries to validate the token against each cached cert.
 Returns the token payload or raises a ValidationError or
  nil, which means none of the certs validated.