Adicionando suporte CORS a um proxy de API

Esta página se aplica ao Apigee e ao Apigee híbrido .

Veja a documentação do Apigee Edge .

CORS (Cross-origin resource sharing) é um mecanismo padrão que permite que chamadas XMLHttpRequest (XHR) em JavaScript executadas em uma página da web interajam com recursos de domínios não originais. CORS é uma solução comumente implementada para a política de mesma origem , aplicada por todos os navegadores. Por exemplo, se você fizer uma chamada XHR para a API do Twitter a partir de um código JavaScript em execução no seu navegador, a chamada falhará. Isso ocorre porque o domínio que serve a página para o seu navegador não é o mesmo que serve a API do Twitter. O CORS oferece uma solução para esse problema, permitindo que os servidores optem por fornecer compartilhamento de recursos entre origens.

Caso de uso típico para CORS

O código JQuery a seguir chama um serviço de destino fictício. Se executado no contexto de um navegador (uma página web), a chamada falhará devido à política de mesma origem:

<script>
var url = "http://service.example.com";
$(document).ready(function(){
  $("button").click(function(){
    $.ajax({
        type:"GET",
        url:url,
        async:true,
        dataType: "json",
           success: function(json) {
              // Parse the response.
              // Do other things.
           },
           error: function(xhr, status, err) {
              // This is where we end up!
            }
    });
  });
});
</script>

Uma solução para esse problema é criar um proxy de API da Apigee que chame a API de serviço no back-end. Lembre-se de que a Apigee fica entre o cliente (um navegador, neste caso) e a API de back-end (o serviço). Como o proxy de API é executado no servidor, e não em um navegador, ele consegue chamar o serviço com sucesso. Depois, basta anexar cabeçalhos CORS à resposta TargetEndpoint. Desde que o navegador seja compatível com CORS, esses cabeçalhos sinalizam ao navegador que não há problema em flexibilizar sua política de mesma origem, permitindo que a chamada de API entre origens seja bem-sucedida.

Após a criação do proxy com suporte a CORS, você poderá chamar a URL do proxy da API em vez do serviço de back-end no seu código do lado do cliente. Por exemplo:

<script>
var url = "http://myorg-test.apigee.net/v1/example";
$(document).ready(function(){
  $("button").click(function(){
    $.ajax({
        type:"GET",
        url:url,
        async:true,
        dataType: "json",
           success: function(json) {
              // Parse the response.
              // Do other things.
           },
           error: function(xhr, status, err) {
              // This time, we do not end up here!
            }
    });
  });
});
</script>

Anexando a política CORS ao PreFlow de solicitação do ProxyEndpoint

Anexando uma política Add CORS a um novo proxy de API

Você pode adicionar suporte a CORS a um proxy de API anexando uma política Adicionar CORS ao proxy de API das seguintes maneiras:

  • Ao criar a política selecionando a caixa de seleção Adicionar cabeçalhos CORS na página Segurança do assistente Criar um proxy
  • Adicionando-o posteriormente na caixa de diálogo Adicionar política

Quando você adiciona a política CORS marcando a caixa de seleção, uma política chamada Adicionar CORS é adicionada automaticamente ao sistema e anexada ao pré-fluxo de solicitação TargetEndpoint .

A política Adicionar CORS adiciona os cabeçalhos apropriados à resposta. Basicamente, os cabeçalhos informam ao navegador com quais origens ele compartilhará seus recursos, quais métodos ele aceita e assim por diante. Você pode ler mais sobre esses cabeçalhos CORS na Recomendação W3C sobre Compartilhamento de Recursos entre Origens .

Você deve modificar a política da seguinte forma:

  • Adicione os cabeçalhos content-type e authorization (necessários para dar suporte à autenticação básica ou OAuth2) ao cabeçalho Access-Control-Allow-Headers , conforme mostrado no trecho de código abaixo.
  • Para autenticação OAuth2, talvez seja necessário tomar medidas para corrigir comportamentos não compatíveis com RFC .
<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, authorization</AllowHeaders>
    <ExposeHeaders>*</ExposeHeaders>
    <MaxAge>3628800</MaxAge>
    <AllowCredentials>false</AllowCredentials>
    <GeneratePreflightResponse>true</GeneratePreflightResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</CORS>

Adicionando cabeçalhos CORS a um proxy existente

Novo Editor de Proxy

Para adicionar a política CORS a um proxy de API existente:

  1. Se você estiver usando a interface do usuário do Apigee no console do Cloud : selecione Desenvolvimento de proxy > Proxies de API .

    Se você estiver usando a interface clássica do Apigee : selecione Desenvolver > Proxies de API e, no painel Proxies , selecione o ambiente para o proxy.

  2. Selecione o proxy de API ao qual você deseja adicionar a política CORS.
  3. No editor do novo proxy de API, clique na guia Desenvolver .
  4. No painel esquerdo, clique no botão + na linha Políticas .
  5. Na caixa de diálogo Criar política , clique no campo Selecionar tipo de política , role para baixo até Segurança e selecione CORS .

  6. Insira os detalhes da política e clique em Criar .

  7. No painel esquerdo, clique em PreFlow em Target Endpoints > default .
  8. Clique no botão + ao lado de PreFlow no painel Solicitação , no canto inferior direito do Editor Visual.
  9. Na caixa de diálogo Adicionar etapa de política , selecione a política CORS .
  10. Clique em Adicionar para anexar a política.

Editor de Proxy Clássico

Para adicionar a política CORS a um proxy de API existente:

  1. Faça login na interface do usuário do Apigee .
  2. Selecione Desenvolver > Proxies de API na barra de navegação à esquerda.
  3. Se você vir o botão Experimentar agora , clique nele para exibir a nova visualização Revelação .

    A visualização Revelação é mostrada abaixo.

    Desenvolver visualização no Editor de Proxy

  4. Selecione o proxy de API ao qual você deseja adicionar a política CORS.
  5. No editor do novo proxy de API, clique na aba Desenvolver :
  6. No painel esquerdo do Navegador, clique em PreFlow em Endpoints de destino > padrão .
  7. Clique no botão "+Etapa" na parte superior, correspondente ao Pré-fluxo de Solicitação. Isso exibirá uma lista categorizada de todas as políticas que você pode criar.
  8. Selecione CORS na categoria Segurança .
  9. Forneça um nome, como Add CORS e clique em Adicionar .

Lidando com solicitações de pré-voo do CORS

O pré-voo CORS refere-se ao envio de uma solicitação a um servidor para verificar se ele oferece suporte a CORS. As respostas típicas do pré-voo incluem as origens das quais o servidor aceitará solicitações CORS, uma lista de métodos HTTP suportados para solicitações CORS, cabeçalhos que podem ser usados ​​como parte da solicitação de recurso, o tempo máximo de cache da resposta do pré-voo, entre outros. Se o serviço não indicar suporte a CORS ou não desejar aceitar solicitações entre origens da origem do cliente, a política de origens cruzadas do navegador será aplicada e quaisquer solicitações entre domínios feitas pelo cliente para interagir com recursos hospedados naquele servidor falharão.

Normalmente, as solicitações de pré-voo CORS são feitas com o método HTTP OPTIONS. Quando um servidor que suporta CORS recebe uma solicitação OPTIONS, ele retorna um conjunto de cabeçalhos CORS ao cliente que indicam seu nível de suporte a CORS. Como resultado desse handshake, o cliente sabe o que pode solicitar do domínio não original.

Para obter mais informações sobre pré-voo, consulte a Recomendação W3C sobre Compartilhamento de Recursos entre Origens . Além disso, há diversos blogs e artigos sobre CORS que você pode consultar.

O Apigee não inclui uma solução de pré-voo CORS pronta para uso, mas é possível implementá-la, conforme descrito nesta seção. O objetivo é que o proxy avalie uma solicitação OPTIONS em um fluxo condicional. O proxy pode então enviar uma resposta apropriada ao cliente.

Vamos analisar um fluxo de exemplo e, em seguida, discutir as partes que lidam com a solicitação de pré-voo:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <Flows>
        <Flow name="OptionsPreFlight">
            <Request>
                <Step>
                    <Name>add-cors</Name>
                </Step>
            </Request>
            <Response/>
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
        </Flow>
    </Flows>

    <PreFlow name="PreFlow">
        <Request/>
        <Response/>

    </PreFlow>
    <HTTPProxyConnection>
        <BasePath>/v1/cnc</BasePath>
        <VirtualHost>default</VirtualHost>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="NoRoute">
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
    </RouteRule>
    <RouteRule name="default">
        <TargetEndpoint>default</TargetEndpoint>
   </RouteRule>
   <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
</ProxyEndpoint>

As principais partes deste ProxyEndpoint são as seguintes:

  • Uma RouteRule é criada para um destino NULL com uma condição para a solicitação OPTIONS. Observe que não há um TargetEndpoint especificado. Se a solicitação OPTIONS for recebida e os cabeçalhos de solicitação Origin e Access-Control-Request-Method não forem nulos, o proxy retornará imediatamente os cabeçalhos CORS em uma resposta ao cliente (ignorando o destino padrão de "backend"). Para obter detalhes sobre condições de fluxo e RouteRule, consulte Condições com variáveis ​​de fluxo .
    <RouteRule name="NoRoute">
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
    </RouteRule>
  • Um fluxo OptionsPreFlight é criado e adiciona uma política Add CORS, contendo os cabeçalhos CORS, ao fluxo se uma solicitação OPTIONS for recebida e os cabeçalhos de solicitação Origin e Access-Control-Request-Method não forem nulos.
     <Flow name="OptionsPreFlight">
                <Request>
                    <Step>
                        <Name>add-cors</Name>
                    </Step>
                </Request>
                <Response/>
            <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
     </Flow>