Stai visualizzando la documentazione di Apigee Edge.
Consulta la
documentazione di Apigee X. info
CORS (condivisione delle risorse multiorigine) è un meccanismo standard che consente alle chiamate JavaScript XMLHttpRequest (XHR) eseguite in una pagina web di interagire con le risorse di domini non di origine. CORS è una soluzione comunemente implementata per i "criteri della stessa origine" applicati 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 browser non è lo stesso del dominio che pubblica l'API Twitter. CORS fornisce una soluzione a questo problema consentendo ai server di "attivare" la condivisione delle risorse multiorigine.
Video:guarda un breve video per scoprire come abilitare CORS in un proxy API.
Caso d'uso tipico per 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 dei criteri 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 nel backend. Ricorda che Edge 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, può chiamare il servizio correttamente. A questo punto, non devi fare altro che collegare le intestazioni CORS alla risposta TargetEndpoint. A condizione che il browser supporti CORS, queste intestazioni segnalano al browser che è possibile "rilassare" i criteri della stessa origine, consentendo alla chiamata API tra origini di avere esito positivo.
Una volta creato il proxy con il 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>
Collegare una policy Aggiungi CORS a un nuovo proxy API
Puoi aggiungere il supporto CORS a un proxy API collegando una policy "Aggiungi CORS" al proxy API quando lo crei. Per aggiungere questa policy, seleziona la casella di controllo Aggiungi intestazioni CORS in nella pagina Sicurezza della procedura guidata Crea un proxy.
Quando selezioni questa casella di controllo, una policy denominata Aggiungi CORS viene aggiunta automaticamente al sistema e collegata al preflow della risposta TargetEndpoint, come mostrato nella figura seguente:

La policy Aggiungi CORS viene implementata come policy AssignMessage, che aggiunge le intestazioni appropriate alla risposta. In pratica, le intestazioni consentono al browser di sapere con quali origini condividerà le proprie risorse, quali metodi accetta e così via. Puoi leggere ulteriori informazioni su queste intestazioni CORS nella raccomandazione W3C sulla condivisione delle risorse tra origini.
Devi modificare la policy come segue:
- Aggiungi le intestazioni
content-typeeauthorization(necessarie per supportare l'autenticazione di base o OAuth2) all'intestazioneAccess-Control-Allow-Headers, come mostrato nell'estratto di codice riportato di seguito. - Per l'autenticazione OAuth2, potrebbe essere necessario eseguire passaggi per correggere il comportamento non conforme alle RFC.
- Ti consigliamo di utilizzare
<Set>per impostare le intestazioni CORS anziché<Add>, come mostrato nell'estratto riportato di seguito. Quando utilizzi<Add>, se l'intestazioneAccess-Control-Allow-Originesiste già, riceverai il seguente errore:The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.Per ulteriori informazioni, consulta Errore CORS : l'intestazione contiene più valori '*, *', ma ne è consentito solo uno.
<AssignMessage async="false" continueOnError="false" enabled="true" name="add-cors"> <DisplayName>Add CORS</DisplayName> <FaultRules/> <Properties/> <Set> <Headers> <Header name="Access-Control-Allow-Origin">{request.header.origin}</Header> <Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept, content-type, authorization</Header> <Header name="Access-Control-Max-Age">3628800</Header> <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header> </Headers> </Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew="false" transport="http" type="response"/> </AssignMessage>
Aggiungere intestazioni CORS a un proxy esistente
Devi creare manualmente una nuova policy Assign Message e copiarvi il codice della policy Aggiungi CORS elencata nella sezione precedente. Quindi, collega la policy al preflow della risposta di TargetEndpoint del proxy API. Puoi modificare i valori delle intestazioni in base alle esigenze. Per ulteriori informazioni sulla creazione e sul collegamento delle policy, consulta Che cos'è una policy?.
Gestire le richieste preflight CORS
Il termine preflight CORS si riferisce all'invio di una richiesta a un server per verificare se lo 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 come parte della richiesta di risorse, il tempo massimo per cui 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, verranno applicati i criteri multiorigine del browser e tutte le richieste tra domini effettuate dal client per interagire con le risorse ospitate su quel server non andranno 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 al client un insieme di intestazioni CORS che indicano il livello di supporto CORS. Di conseguenza, il client sa cosa può richiedere dal dominio non di origine.
Per ulteriori informazioni sul preflight, consulta la raccomandazione W3C sulla condivisione delle risorse tra origini. Inoltre, esistono numerosi blog e articoli su CORS a cui puoi fare riferimento.
Apigee non include una soluzione preflight CORS predefinita, 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.
Diamo un'occhiata a un flusso di esempio e poi discutiamo le parti che gestiscono la richiesta preflight:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Description/>
<Flows>
<Flow name="OptionsPreFlight">
<Request/>
<Response>
<Step>
<Name>add-cors</Name>
</Step>
</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 è specificato alcun TargetEndpoint. Se viene ricevuta la richiesta OPTIONS e le intestazioni delle richieste Origin e
Access-Control-Request-Method non sono nulle, il proxy restituisce immediatamente le
intestazioni CORS in una risposta al client (ignorando la destinazione "backend" predefinita).
Per i dettagli sulle condizioni del flusso e su 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 una policy Aggiungi 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 nulle.
<Flow name="OptionsPreFlight"> <Request/> <Response> <Step> <Name>add-cors</Name> </Step> </Response> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </Flow>
Utilizzare la soluzione CORS di esempio
Una soluzione CORS di esempio, implementata come flusso condiviso, è disponibile su GitHub. Importa il bundle del flusso condiviso nel tuo ambiente e collegalo utilizzando gli hook di flusso o direttamente ai flussi del proxy API. Per i dettagli, consulta il file README di CORS-Shared-FLow fornito con l'esempio.