Aggiunta del supporto CORS a un proxy API

Questa pagina si applica a Apigee e Apigee ibrido.

Visualizza la documentazione di Apigee Edge.

CORS (condivisione delle risorse tra origini) è un meccanismo standard che consente alle chiamate JavaScript XMLHttpRequest (XHR) eseguite in una pagina web di interagire con risorse da domini non di origine. CORS è una soluzione comunemente implementata per il criterio della stessa origine che viene applicato da tutti i browser. Ad esempio, se effettui una chiamata XHR all'API Twitter dal codice JavaScript in esecuzione nel browser, la chiamata non andrà a buon fine. Questo perché il dominio che pubblica la pagina nel tuo browser non è uguale al dominio che pubblica l'API Twitter. CORS offre una soluzione a questo problema consentendo ai server di eseguire l'attivazione se vogliono fornire la condivisione delle risorse tra origini.

Caso d'uso tipico di CORS

Il codice JQuery riportato di seguito chiama un servizio di destinazione fittizio. Se eseguita dal contesto di un browser (una pagina web), la chiamata non riuscirà a causa del criterio della stessa origine:

<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>

Una soluzione a questo problema è creare un proxy API Apigee che chiama l'API di servizio sul backend. Ricorda che Apigee si trova tra il client (in questo caso un browser) e l'API backend (il servizio). Poiché il proxy API viene eseguito sul server, non in un browser, è in grado di chiamare il servizio. Quindi, devi solo collegare le intestazioni CORS alla risposta TargetEndpoint. Finché il browser supporta CORS, queste intestazioni indicano al browser che va bene rilassare il criterio della stessa origine, consentendo la chiamata API multiorigine.

Una volta creato il proxy con supporto CORS, puoi chiamare l'URL del proxy API anziché il servizio di backend nel codice lato client. Ad esempio:

<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>

Collegamento del criterio CORS alla richiesta PreFlow del ProxyEndpoint

Collegamento di un criterio Aggiungi CORS a un nuovo proxy API

Puoi aggiungere il supporto CORS a un proxy API collegando un criterio Aggiungi CORS al proxy API nei seguenti modi:

  • Quando crei il criterio selezionando la casella di controllo Aggiungi intestazioni CORS nella pagina Sicurezza della procedura guidata Crea un proxy
  • Aggiungendolo in un secondo momento dalla finestra di dialogo Aggiungi criterio.

Quando aggiungi il criterio CORS selezionando la casella di controllo, un criterio denominato Aggiungi CORS viene aggiunto automaticamente al sistema e associato al preflusso della richiesta TargetEndpoint.

Il criterio Aggiungi CORS aggiunge le intestazioni appropriate alla risposta. Fondamentalmente, le intestazioni consentono al browser di sapere con quali origini condividerà le sue risorse, quali metodi accetta e così via. Per saperne di più su queste intestazioni CORS, consulta il suggerimento W3C per la condivisione delle risorse tra origini.

Ti consigliamo di modificare la norma nel seguente modo:

  • Aggiungi le intestazioni content-type e authorization (necessarie per supportare l'autenticazione di base o OAuth2) all'intestazione Access-Control-Allow-Headers, come mostrato nell'estratto del codice riportato di seguito.
  • Per l'autenticazione OAuth2, potrebbe essere necessario seguire alcuni passaggi per correggere il comportamento non conforme alla specifica 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>

Aggiunta di intestazioni CORS a un proxy esistente

Nuovo editor proxy

Per aggiungere il criterio CORS a un proxy API esistente:

  1. Se utilizzi la UI di Apigee nella console Cloud: seleziona Sviluppo proxy > Proxy API.

    Se utilizzi la UI di Apigee classica: seleziona Sviluppo > Proxy API e, nel riquadro Proxy, seleziona l'ambiente per il proxy.

  2. Seleziona il proxy API a cui vuoi aggiungere il criterio CORS.
  3. Nell'editor del nuovo proxy API, fai clic sulla scheda Sviluppo.
  4. Nel riquadro a sinistra, fai clic sul pulsante + nella riga Norme.
  5. Nella finestra di dialogo Crea criterio, fai clic nel campo Seleziona il tipo di criterio e scorri verso il basso fino a Sicurezza, quindi seleziona CORS.

  6. Inserisci i dettagli del criterio e fai clic su Crea.

  7. Nel riquadro a sinistra, fai clic su PreFlow in Endpoint di destinazione > predefiniti.
  8. Seleziona Proxy Endpoints > default > PreFlow nel riquadro a sinistra:

    Seleziona gli endpoint di destinazione per PreFlow in Proxy Explorer.

  9. Fai clic sul pulsante + accanto a PreFlow nel riquadro Risposta in basso a destra nell'Editor visivo:

    Fai clic sul pulsante + accanto a PreFlow nel riquadro Risposta.

  10. Nella finestra di dialogo Aggiungi passaggio criterio, seleziona il criterio CORS.
  11. Fai clic su Aggiungi per allegare il criterio.

Editor proxy classico

Per aggiungere il criterio CORS a un proxy API esistente:

  1. Accedi all'UI di Apigee.
  2. Seleziona Develop > API Proxy nella barra di navigazione a sinistra.
  3. Se vedi il pulsante Prova ora, fai clic per aprire la nuova vista Sviluppo.

    Di seguito è mostrata la vista Sviluppo.

    Visualizzazione Sviluppo nell&#39;editor proxy

  4. Seleziona il proxy API a cui vuoi aggiungere il criterio CORS.
  5. Nell'editor del nuovo proxy API, fai clic sulla scheda Sviluppo:
  6. Nel riquadro di navigazione a sinistra, fai clic su PreFlow in Endpoint di destinazione > predefiniti.
  7. Fai clic sul pulsante +Step in alto, corrispondente a Request PreFlow. Viene visualizzato un elenco categorizzato di tutti i criteri che puoi creare.
  8. Seleziona CORS nella categoria Sicurezza.
  9. Specifica un nome, ad esempio Add CORS, e fai clic su Aggiungi.

Gestione delle richieste preflight CORS

Con preflight CORS si intende l'invio di una richiesta a un server per verificare se supporta CORS. Le risposte preflight tipiche includono le origini da cui il server accetterà le richieste CORS, un elenco di metodi HTTP supportati per le richieste CORS, intestazioni che possono essere utilizzate come parte della richiesta di risorse, il tempo massimo che la risposta preflight verrà memorizzata nella cache e altro ancora. Se il servizio non indica il supporto CORS o non vuole accettare richieste multiorigine dall'origine del client, verrà applicato il criterio multiorigine del browser e qualsiasi richiesta tra domini effettuata dal client per interagire con le risorse ospitate su quel server non andrà a buon fine.

In genere, le richieste preflight CORS vengono effettuate con il metodo HTTP OPTIONS. Quando un server che supporta CORS riceve una richiesta OPTIONS, restituisce un insieme di intestazioni CORS al client che indicano il livello di supporto CORS. Come risultato di questo handshake, il client sa cosa può richiedere dal dominio non di origine.

Per ulteriori informazioni sull'elaborazione preflight, consulta il consiglio del W3C per la condivisione delle risorse tra origini. Esistono, inoltre, numerosi blog e articoli su CORS a cui puoi fare riferimento.

Apigee non include una soluzione preflight CORS pronta all'uso, ma è possibile implementarla, come descritto in questa sezione. L'obiettivo è che il proxy valuti una richiesta OPTIONS in un flusso condizionale. Il proxy può quindi inviare una risposta appropriata al client.

Esaminiamo un flusso di esempio e poi parliamo delle parti che gestiscono la richiesta preflight:

<?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>

Le parti principali di questo ProxyEndpoint sono le seguenti:

  • Una RouteRule viene creata verso una destinazione NULL con una condizione per la richiesta OPTIONS. Tieni presente che non è specificato nessun TargetEndpoint. Se la richiesta OPTIONS viene ricevuta e le intestazioni delle richieste Origin e Access-Control-Request-Method non sono nulle, il proxy restituisce immediatamente le intestazioni CORS in risposta al client (ignorando l'effettivo target di "backend" predefinito). Per maggiori dettagli sulle condizioni di flusso e RouteRule, consulta Condizioni con variabili di flusso.
    <RouteRule name="NoRoute">
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
    </RouteRule>
    
  • Viene creato un flusso OptionsPreFlight che aggiunge un criterio Add CORS contenente le intestazioni CORS al flusso se viene ricevuta una richiesta OPTIONS e le intestazioni delle richieste Origin e Access-Control-Request-Method non sono null.
     <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>