Política de CORS

Esta página se aplica a Apigee y Apigee hybrid.

Consulta la documentación de Apigee Edge.

El uso compartido de recursos entre dominios (CORS) es un mecanismo estándar que permite que las llamadas XMLHttpRequest (XHR) de JavaScript ejecutadas en una página web interactúen con recursos de dominios que no son el de origen. CORS es una solución que se implementa habitualmente para la política de coincidencia de origen que aplican todos los navegadores.

Por ejemplo, si haces una llamada XHR a la API de Twitter desde un código JavaScript que se ejecuta en tu navegador, la llamada fallará. Esto se debe a que el dominio que sirve la página a tu navegador no es el mismo que el que sirve la API de Twitter. CORS ofrece una solución a este problema, ya que permite que los servidores habiliten esta opción si quieren ofrecer el uso compartido de recursos entre dominios.

Un caso práctico de CORS es la función Probar esta API de SmartDocs del portal para desarrolladores. Para obtener información, consulta Configurar un proxy de API para que admita el panel Probar esta API.

La política de CORS permite a los clientes de Apigee definir políticas de CORS para las APIs que consumen las aplicaciones web.

Esta política es una política estándar y se puede implementar en cualquier tipo de entorno. Para obtener información sobre los tipos de políticas y la disponibilidad de cada tipo de entorno, consulta Tipos de políticas.

Elemento <CORS>

Define la política de CORS.

Valor predeterminado Consulta la pestaña Política predeterminada que aparece más abajo.
¿Es obligatorio? Obligatorio
Tipo Objeto complejo
Elemento principal N/A
Elementos secundarios <AllowCredentials>
<AllowHeaders>
<AllowMethods>
<AllowOrigins>
<DisplayName>
<ExposeHeaders>
<GeneratePreflightResponse>
<IgnoreUnresolvedVariables>
<MaxAge>

El elemento <CORS> utiliza la siguiente sintaxis:

Sintaxis

El elemento <CORS> utiliza la siguiente sintaxis:


<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <DisplayName>DISPLAY_NAME</DisplayName>
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <AllowMethods>[GET, PUT, POST, DELETE, ...|*]</AllowMethods>
  <AllowHeaders>[origin, x-requested-with, accept, content-type, ...]</AllowHeaders>
  <ExposeHeaders>[X-CUSTOM-HEADER-A, X-CUSTOM-HEADER-B, ... | *]</ExposeHeaders>
  <MaxAge>[integer|-1]</MaxAge>
  <AllowCredentials>[false|true]</AllowCredentials>
  <GeneratePreflightResponse>[false|true]</GeneratePreflightResponse>
  <IgnoreUnresolvedVariables>[false|true]</IgnoreUnresolvedVariables>
</CORS>

Política predeterminada

En el siguiente ejemplo se muestran los ajustes predeterminados al añadir la política de CORS a tu flujo en la interfaz de Edge:

<CORS continueOnError="false" enabled="true" name="add-cors">
    <DisplayName>Add CORS</DisplayName>
    <AllowOrigins>{request.header.origin}</AllowOrigins>
    <AllowMethods>GET, PUT, POST, DELETE</AllowMethods>
    <AllowHeaders>origin, x-requested-with, accept, content-type</AllowHeaders>
    <ExposeHeaders>*</ExposeHeaders>
    <MaxAge>3628800</MaxAge>
    <AllowCredentials>false</AllowCredentials>
    <GeneratePreflightResponse>true</GeneratePreflightResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</CORS>

Cuando insertas una nueva política CORS en la interfaz de Apigee, la plantilla contiene stubs para todas las operaciones posibles. Normalmente, se seleccionan las operaciones que se quieren realizar con esta política y se eliminan el resto de los elementos secundarios. Por ejemplo, si quiere especificar los métodos HTTP permitidos para acceder al recurso, utilice el elemento <AllowMethods> y quite los demás elementos secundarios de la política para que sea más legible.

Este elemento tiene los siguientes atributos, que son comunes a todas las políticas:

Atributo Predeterminado ¿Es obligatorio? Descripción
name N/A Obligatorio

El nombre interno de la política. El valor del atributo name puede contener letras, números, espacios, guiones, guiones bajos y puntos. Este valor no puede superar los 255 caracteres.

Opcionalmente, usa el elemento <DisplayName> para etiquetar la política en el editor de proxy de la interfaz de gestión con un nombre diferente en lenguaje natural.

continueOnError falso Opcional Asigna el valor false para devolver un error cuando falle una política. Este es el comportamiento esperado de la mayoría de las políticas. Asigna el valor true para que la ejecución del flujo continúe incluso después de que falle una política. Consulta también:
enabled true Opcional Asigna el valor true para aplicar la política. Selecciona false para desactivar la política. La política no se aplicará aunque siga adjunta a un flujo.
async   falso Obsoleto Este atributo está obsoleto.

Cada uno de los elementos secundarios se describe en las secciones siguientes.

Ejemplos

En las secciones siguientes se proporcionan ejemplos de todos los elementos secundarios.

Referencia de elemento secundario

En esta sección se describen los elementos secundarios de <CORS>.

<AllowCredentials>

Indica si el llamante tiene permiso para enviar la solicitud real (no la de comprobación previa) usando credenciales. Se traduce al encabezado Access-Control-Allow-Credentials.

Valor predeterminado Si no se especifica, no se definirá Access-Control-Allow-Credentials.
¿Es obligatorio? Opcional
Tipo Booleano
Elemento principal <CORS>
Elementos secundarios Ninguno

El elemento <AllowCredentials> utiliza la siguiente sintaxis:

Sintaxis

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <AllowCredentials>[false|true]</AllowCredentials>
</CORS>
      

Ejemplo

This example sets the Access-Control-Allow-Credentials header to false. That is, the caller is not allowed to send the actual request (not the preflight) using credentials.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <AllowCredentials>false</AllowCredentials>
</CORS>

<AllowHeaders>

Lista de encabezados HTTP que se pueden usar al solicitar el recurso. Serializado en el encabezado Access-Control-Allow-Headers.

Valor predeterminado Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers
¿Es obligatorio? Opcional
Tipo Cadena, con compatibilidad con plantillas de mensajes*
Elemento principal <CORS>
Elementos secundarios Ninguno

* Para obtener más información, consulta ¿Qué es una plantilla de mensaje?

El elemento <AllowHeaders> utiliza la siguiente sintaxis:

Sintaxis

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <AllowHeaders>[origin, x-requested-with, accept, content-type, ...]</AllowHeaders>
</CORS>

Ejemplo

CORS AllowOrigins example

This example specifies the HTTP headers that can be used when requesting the resource.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <AllowHeaders>origin, x-requested-with, accept, content-type</AllowHeaders>
</CORS>

<AllowMethods>

Lista de métodos HTTP permitidos para acceder al recurso. El contenido se serializará en el encabezado Access-Control-Allow-Methods.

Valor predeterminado GET, POST, HEAD, OPTIONS
¿Es obligatorio? Opcional
Tipo Cadena, con compatibilidad con plantillas de mensajes*
Elemento principal <CORS>
Elementos secundarios Ninguno

* Para obtener más información, consulta ¿Qué es una plantilla de mensaje?

El elemento <AllowMethods> utiliza la siguiente sintaxis:

Sintaxis

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <AllowMethods>[GET, PUT, POST, DELETE, ...|*]</AllowMethods>
</CORS>

Ejemplo:
Lista

This example specifies the HTTP methods that are allowed to access the resource.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <AllowMethods>GET, PUT, POST, DELETE</AllowMethods>
</CORS>

Ejemplo:
Comodín

This example specifies that all HTTP methods are allowed to access the resource.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <AllowMethods>*</AllowMethods>
</CORS>

<AllowOrigins>

Lista de orígenes que tienen permiso para acceder al recurso. Usa un asterisco (*) para habilitar el acceso a un recurso desde cualquier origen. De lo contrario, proporcione una lista de permitidos de orígenes separados por comas. Si se encuentra una coincidencia, la Access-Control-Allow-Origin saliente se define como el origen proporcionado por el cliente.

Valor predeterminado N/A
¿Es obligatorio? Obligatorio
Tipo Cadena, con compatibilidad con plantillas de mensajes*
Elemento principal <CORS>
Elementos secundarios Ninguno

* Para obtener más información, consulta ¿Qué es una plantilla de mensaje?

El elemento <AllowOrigins> utiliza la siguiente sintaxis:

Sintaxis

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
</CORS>

Ejemplo:
URL único

This example specifies a single URL origin that is allowed to access the resource.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>https://www.w3.org</AllowOrigins>
</CORS>

Ejemplo:
Varias URLs

This example specifies multiple origins that are allowed to access the resource.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>https://www.w3.org, https://www.apache.org</AllowOrigins>
</CORS>

Ejemplo:
Variable de contexto

This example specifies a context variable that represents one or more origins that are allowed to access the resource.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{origins.list}</AllowOrigins>
</CORS>

Ejemplo:
Variable de flujo

This example specifies a flow variable that represents one origin that is allowed to access the resource.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
</CORS>

Ejemplo:
Comodín

This example specifies that all origins are allowed to access the resource.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>*</AllowOrigins>
</CORS>

<DisplayName>

Se usa junto con el atributo name para etiquetar la política en el editor de proxy de la interfaz de usuario de gestión con un nombre diferente que suene más natural.

El elemento <DisplayName> es común a todas las políticas.

Valor predeterminado N/A
¿Es obligatorio? Opcional. Si omite <DisplayName>, se usará el valor del atributo name de la política.
Tipo Cadena
Elemento principal <PolicyElement>
Elementos secundarios Ninguno

El elemento <DisplayName> utiliza la siguiente sintaxis:

Sintaxis

<PolicyElement>
  <DisplayName>POLICY_DISPLAY_NAME</DisplayName>
  ...
</PolicyElement>

Ejemplo

<PolicyElement>
  <DisplayName>My Validation Policy</DisplayName>
</PolicyElement>

El elemento <DisplayName> no tiene atributos ni elementos secundarios.

<ExposeHeaders>

Lista de encabezados HTTP a los que pueden acceder los navegadores o un asterisco (*) para permitir todos los encabezados HTTP. Serializado en el encabezado Access-Control-Expose-Headers.

Valor predeterminado Si no se especifica, no se definirá Access-Control-Expose-Headers. Los encabezados no simples no se exponen de forma predeterminada.
¿Es obligatorio? Opcional
Tipo Cadena, con compatibilidad con plantillas de mensajes*
Elemento principal <CORS>
Elementos secundarios Ninguno

* Para obtener más información, consulta ¿Qué es una plantilla de mensaje?

El elemento <ExposeHeaders> utiliza la siguiente sintaxis:

Sintaxis

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <ExposeHeaders>[X-CUSTOM-HEADER-A, X-CUSTOM-HEADER-B, ... | *]</ExposeHeaders>
</CORS>

Ejemplo

This example specifies that the browsers are allowed to access all HTTP headers.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <ExposeHeaders>*</ExposeHeaders>
</CORS>

<GeneratePreflightResponse>

Indica si la política debe generar y devolver la respuesta de solicitud preparatoria CORS. Si false, no se envía ninguna respuesta. En su lugar, se rellenan las siguientes variables de flujo:

  • cross_origin_resource_sharing.allow.credentials
  • cross_origin_resource_sharing.allow.headers
  • cross_origin_resource_sharing.allow.methods
  • cross_origin_resource_sharing.allow.origin
  • cross_origin_resource_sharing.allow.origins.list
  • cross_origin_resource_sharing.expose.headers
  • cross_origin_resource_sharing.max.age
  • cross_origin_resource_sharing.preflight.accepted
  • cross_origin_resource_sharing.request.headers
  • cross_origin_resource_sharing.request.method
  • cross_origin_resource_sharing.request.origin
  • cross_origin_resource_sharing.request.type
Valor predeterminado true
¿Es obligatorio? Opcional
Tipo Booleano
Elemento principal <CORS>
Elementos secundarios Ninguno

El elemento <GeneratePreflightResponse> utiliza la siguiente sintaxis:

Sintaxis

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <GeneratePreflightResponse>[false|true]</GeneratePreflightResponse>
  <GeneratePreflightResponse>[false|true]</GeneratePreflightResponse>
</CORS>

Ejemplo

This example specifies that the policy should generate and return the CORS preflight response.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <GeneratePreflightResponse>true</GeneratePreflightResponse>
</CORS>

<IgnoreUnresolvedVariables>

Determina si el procesamiento se detiene cuando se encuentra una variable sin resolver. Se define como true para ignorar las variables sin resolver y continuar con el procesamiento; de lo contrario, false.

Valor predeterminado true
¿Es obligatorio? Opcional
Tipo Booleano
Elemento principal <CORS>
Elementos secundarios Ninguno

El elemento <IgnoreUnresolvedVariables> utiliza la siguiente sintaxis:

Sintaxis

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <IgnoreUnresolvedVariables>[false|true]</IgnoreUnresolvedVariables>
</CORS>

Ejemplo

This example specifies that processing continues when an unresolved variable is encountered.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</CORS>

<MaxAge>

Especifica durante cuánto tiempo se pueden almacenar en caché los resultados de una solicitud de comprobación previa en segundos. Si se asigna el valor -1 al encabezado Access-Control-Max-Age, se inhabilita el almacenamiento en caché, por lo que se requiere una comprobación previa OPTIONS para todas las llamadas.-1 Esto se define en la especificación Access-Control-Max-Age.

Valor predeterminado 1800
¿Es obligatorio? Opcional
Tipo Entero
Elemento principal <CORS>
Elementos secundarios Ninguno

El elemento <MaxAge> utiliza la siguiente sintaxis:

Sintaxis

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <MaxAge>[integer|-1]</MaxAge>
</CORS>

Ejemplo:
Caché

This example specifies that the results of a preflight request can be cached for 3628800 seconds.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <MaxAge>3628800</MaxAge>
</CORS>

Ejemplo:
Sin caché

This example specifies that the results of a preflight request cannot be cached.

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <MaxAge>-1</MaxAge>
</CORS>

Notas de uso

Solicitudes de OPTIONS

Cuando la política de CORS recibe y procesa una solicitud OPTIONS, la ejecución del flujo del proxy se transfiere directamente al PreFlow de respuesta del proxy, se omiten por completo los flujos de solicitud y la ejecución continúa desde ahí. No es necesario crear una condición para ignorar la solicitud OPTIONS en el flujo de solicitudes de proxy.

En las llamadas posteriores, cuando se ejecute la política de CORS, si el MaxAge definido en la política no ha caducado, el flujo continuará con normalidad. Durante el flujo de respuesta final, justo antes de "Respuesta enviada al cliente", un paso de ejecución de CORS especial, "CORSResponseOrErrorFlowExecution", define los encabezados de respuesta de CORS (Access-Control-Allow-Credentials, Access-Control-Allow-Origin y Access-Control-Expose-Headers) para devolver una respuesta validada por CORS.

Códigos de error

This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.

Runtime errors

These errors can occur when the policy executes.

Fault code HTTP status Cause
steps.cors.UnresolvedVariable 500 This error occurs if a variable specified in the CORS policy is either:
  • Out of scope (not available in the specific flow where the policy is being executed)
  • or

  • Can't be resolved (is not defined)

Deployment errors

These errors can occur when you deploy a proxy containing this policy.

Error name Cause
InvalidMaxAge MaxAge is not number
MissingAllowOrigins AllowOrigins is not specified
InvalidHTTPMethods One of the methods in AllowMethods is not valid
AllowHeadersSizeTooLarge The string size in AllowHeaders is too large.
ExposeHeadersSizeTooLarge The string size in ExposeHeaders is too large.

Fault variables

These variables are set when this policy triggers an error at runtime. For more information, see What you need to know about policy errors.

Variables Where Example
fault.name = "FAULT_NAME" FAULT_NAME is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. fault.name Matches "UnresolveVariable"
cors.POLICY_NAME.failed POLICY_NAME is the user-specified name of the policy that threw the fault. cors.AddCORS.failed = true

Example error response

{
   "fault":{
      "detail":{
         "errorcode":"steps.cors.UnresolvedVariable"
      },
      "faultstring":"CORS[AddCORS]: unable to resolve variable wrong.var"
   }
}

Example fault rule

<FaultRule name="Add CORS Fault">
    <Step>
        <Name>Add-CORSCustomUnresolvedVariableErrorResponse</Name>
        <Condition>(fault.name Matches "UnresolvedVariable") </Condition>
    </Step>
    <Condition>(cors.Add-CORS.failed = true) </Condition>
</FaultRule>

Variables de flujo

Se añadirá un objeto CorsFlowInfo FlowInfo y estará disponible para el seguimiento.

Propiedad Tipo Lectura y escritura Descripción Comienza el ámbito
cross_origin_resource_sharing.allow.credentials Booleano Lectura y escritura Valor de <AllowCredentials> Solicitud de proxy
cross_origin_resource_sharing.allow.headers Cadena Lectura y escritura Valor de <AllowHeaders> Solicitud de proxy
cross_origin_resource_sharing.allow.methods Cadena Lectura y escritura Valor de <AllowMethods> Solicitud de proxy
cross_origin_resource_sharing.allow.origin Cadena Lectura y escritura El origen de la solicitud que se permite. Si no está en la lista de permitidos, estará vacío. Solicitud de proxy
cross_origin_resource_sharing.allow.origins.list Cadena Lectura y escritura Valor de <AllowOrigins> Solicitud de proxy
cross_origin_resource_sharing.expose.headers Cadena Lectura y escritura Valor de <ExposeHeaders> Solicitud de proxy
cross_origin_resource_sharing.max.age Entero Lectura y escritura Valor de <MaxAge> Solicitud de proxy
cross_origin_resource_sharing.preflight.accepted Booleano Lectura y escritura Indica si se acepta la solicitud de comprobación previa. Solicitud de proxy
cross_origin_resource_sharing.request.headers Cadena Lectura y escritura Valor del encabezado Access-Control-Request-Headers de la solicitud Solicitud de proxy
cross_origin_resource_sharing.request.method Cadena Lectura y escritura Valor del encabezado Access-Control-Request-Method de la solicitud Solicitud de proxy
cross_origin_resource_sharing.request.origin Cadena Lectura y escritura Igual que request.header.origin Solicitud de proxy
cross_origin_resource_sharing.request.type Cadena Lectura y escritura

Tipo de solicitud CORS. Posibles valores:

  • REAL: una solicitud que no es una solicitud de comprobación previa
  • PRE_FLIGHT: una solicitud preparatoria
Solicitud de proxy