Aggiunta del supporto CORS a un proxy API

Questa pagina si applica ad Apigee e Apigee hybrid.

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 le risorse dei domini non di origine. CORS è una soluzione comunemente implementata al criterio della stessa origine applicato da tutti i browser. Ad esempio, se effettui una chiamata XHR all'API Twitter da codice JavaScript in esecuzione nel browser, la chiamata non andrà a buon fine. Questo perché il dominio che fornisce la pagina al tuo browser non è lo stesso del dominio che fornisce l'API Twitter. CORS offre una soluzione a questo problema consentendo ai server di attivare se vogliono fornire la condivisione delle risorse tra origini.

Caso d'uso tipico di CORS

Il seguente codice JQuery chiama un servizio di destinazione fittizio. Se eseguita nel contesto di un browser (una pagina web), la chiamata non andrà a buon fine 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 chiami l'API del servizio sul backend. Ricorda che Apigee si trova tra il client (in questo caso un browser) e l'API di backend (il servizio). Poiché il proxy API viene eseguito sul server, non in un browser, è in grado di chiamare correttamente il servizio. Quindi, devi solo collegare le intestazioni CORS alla risposta di TargetEndpoint. Finché il browser supporta CORS, queste intestazioni segnalano al browser che può relax il criterio della stessa origine, consentendo la riuscita della 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 al preFlow della richiesta di ProxyEndpoint

Collegamento di un criterio di aggiunta 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, al sistema viene aggiunto automaticamente un criterio denominato Add CORS e viene associato al pre-flusso della richiesta TargetEndpoint.

Il criterio Add CORS aggiunge le intestazioni appropriate alla risposta. In pratica, 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 consiglio W3C per la condivisione delle risorse tra origini.

Devi modificare il criterio, come indicato di seguito:

  • 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 di codice di seguito.
  • Per l'autenticazione OAuth2, potresti dover svolgere dei passaggi per correggere il comportamento non conforme a 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 l'interfaccia utente di Apigee nella console Cloud: seleziona Sviluppo proxy > Proxy API.

    Se utilizzi l'interfaccia utente 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 sul campo Seleziona il tipo di criterio, scorri verso il basso fino a Sicurezza e 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 Endpoint del proxy > predefinito > PreFlow nel riquadro a sinistra:

    Endpoint di destinazione per la selezione 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 del 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'interfaccia utente di Apigee.
  2. Seleziona Sviluppo > Proxy API nella barra di navigazione a sinistra.
  3. Se vedi il pulsante Prova ora, fai clic sul pulsante per aprire la nuova visualizzazione Sviluppa.

    Di seguito è mostrata la visualizzazione 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 +Passaggio in alto, corrispondente al PreFlow della richiesta. 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

Preflight CORS si riferisce all'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, le intestazioni che possono essere utilizzate nell'ambito della richiesta di risorsa, il tempo massimo per la risposta preflight che 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, il criterio multiorigine del browser verrà applicato in modo forzato e le eventuali richieste interdominio effettuate dal client per interagire con le risorse ospitate su quel server avranno esito negativo.

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

Per saperne di più sui preflight, consulta il consiglio W3C sulla 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.

Analizziamo un flusso di esempio, quindi 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:

  • Viene creata una RouteRule per una destinazione NULL con una condizione per la richiesta OPTIONS. Tieni presente che non è stato specificato alcun TargetEndpoint. Se la richiesta OPTIONS viene ricevuta e le intestazioni delle richieste Origin e Access-Control-Request-Method non sono null, il proxy restituisce immediatamente le intestazioni CORS in una risposta al client, ignorando l'effettiva destinazione predefinita di "backend". 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 opzioniPreFlight che aggiunge al flusso un criterio Add CORS, contenente le intestazioni CORS, se viene ricevuta una richiesta OPTIONS e se 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>