Questa pagina si applica ad Apigee e Apigee hybrid.
Visualizza la documentazione di
Apigee Edge.
La condivisione delle risorse tra origini (CORS) è un meccanismo standard che consente alle chiamate XMLHttpRequest (XHR) JavaScript eseguite in una pagina web di interagire con 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 tuo browser non è lo stesso che pubblica l'API Twitter. CORS fornisce una soluzione a questo problema consentendo ai server di attivare la condivisione delle risorse tra origini.
Caso d'uso tipico per CORS
Il seguente codice JQuery chiama un servizio di destinazione fittizio. Se eseguita dal 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 il servizio correttamente. A questo punto, devi solo allegare le intestazioni CORS alla risposta TargetEndpoint. Se il browser supporta CORS, queste intestazioni segnalano al browser che è possibile rilassare i criteri della stessa origine, consentendo la riuscita della chiamata API cross-origin.
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 della policy CORS al PreFlow della richiesta di ProxyEndpoint
Allegare una policy Aggiungi CORS a un nuovo proxy API
Aggiungi il supporto CORS a un proxy API collegando una policy Aggiungi CORS al proxy API.
Il criterio Aggiungi CORS aggiunge le intestazioni appropriate alla risposta. In sostanza, le intestazioni comunicano al browser con quali origini condividerà le risorse, quali metodi accetta e così via. Puoi scoprire di più su queste intestazioni CORS nella raccomandazione W3C per la condivisione delle risorse tra origini diverse.
Devi modificare la norma nel seguente modo:
- 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 intervenire per correggere il comportamento non conforme alla 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
Per aggiungere la policy CORS a un proxy API esistente:
Nella console Google Cloud , vai alla pagina Sviluppo proxy > Proxy API.
- Seleziona il proxy API a cui vuoi aggiungere la policy CORS. L'interfaccia utente mostra i dettagli del proxy nella console Google Cloud .
- Fai clic sulla scheda Sviluppa.
- Nel riquadro di navigazione, fai clic sul pulsante + nella riga Policy.
Nella finestra di dialogo Crea policy, fai clic sul campo Seleziona policy e scorri verso il basso fino a Sicurezza e seleziona CORS.
Inserisci i dettagli della policy e fai clic su Crea.
- Nel riquadro di navigazione, fai clic su PreFlow in Endpoint di destinazione > default.
- Fai clic sul pulsante + accanto a PreFlow nel riquadro Richiesta dell'editor visivo.
- Nella finestra di dialogo Aggiungi passaggio policy, seleziona la policy CORS.
Fai clic su Aggiungi per allegare la policy.
Gestione delle richieste preflight CORS
Il 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 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 di CORS o non vuole accettare richieste multiorigine dall'origine del client, verrà applicata la policy multiorigine del browser e tutte le richieste cross-domain 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. A seguito di questo handshake, il client sa cosa può richiedere dal dominio non di origine.
Per ulteriori informazioni sul controllo preliminare, consulta la raccomandazione W3C sul Cross-Origin Resource Sharing. 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 analizziamo le parti che gestiscono la richiesta di 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 è 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 il target "backend" predefinito effettivo).
Per informazioni dettagliate sulle condizioni del flusso e su RouteRule, consulta la sezione 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 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> <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>