Richiama le API AEM basate su OpenAPI tramite l’app a pagina singola OAuth
Scopri come richiamare le API AEM basate su OpenAPI su AEM as a Cloud Service utilizzando l’autenticazione app a pagina singola OAuth. Segue il flusso PKCE (Proof Key for Code Exchange) di OAuth 2.0 per l’autenticazione basata sull’utente in un’applicazione a pagina singola.
L’autenticazione tramite app a pagina singola OAuth è ideale per le applicazioni basate su JavaScript in esecuzione nel browser. Se non dispongono di un server back-end o se devono recuperare i token di accesso per interagire con le API di AEM per conto di un utente.
Il flusso PKCE estende il tipo di concessione authorization_code di OAuth 2.0, migliorando la sicurezza impedendo l’intercettazione del codice di autorizzazione. Per ulteriori informazioni, consulta la sezione Differenza tra le credenziali da server a server OAuth e da app Web e credenziali app a pagina singola.
Argomenti trattati what-you-learn
In questo tutorial imparerai a:
-
Configura un progetto Adobe Developer Console (ADC) per accedere alle API AEM basate su OpenAPI utilizzando l'autenticazione OAuth Single Page App o comunemente nota come flusso PKCE OAuth 2.0.
-
Implementa il flusso di autenticazione di app a pagina singola OAuth in un’applicazione a pagina singola personalizzata.
- Autenticazione utente IMS e autorizzazione app.
- Accedi al recupero del token utilizzando il flusso PKCE di OAuth 2.0.
- Utilizza il token di accesso per richiamare le API AEM basate su OpenAPI.
Prima di iniziare, assicurati di aver rivisto quanto segue:
Panoramica e flusso funzionale dell’applicazione a pagina singola WKND wknd-spa-overview-and-functional-flow
Esaminiamo cos’è l’applicazione a pagina singola WKND, come viene creata e come funziona.
L'applicazione a pagina singola WKND è un'applicazione a pagina singola basata su React che illustra come ottenere in modo sicuro un token di accesso specifico per l'utente e interagire direttamente con le API di AEM dal lato client. Implementa il flusso di autenticazione PKCE OAuth 2.0 tramite Adobe IMS e si integra con due API chiave di AEM:
- API Sites: per accedere ai modelli per frammenti di contenuto
- API Assets: per la gestione delle cartelle DAM
Il progetto Adobe Developer Console (ADC) è configurato per abilitare l'autenticazione app a pagina singola OAuth, fornendo il client_id richiesto per avviare il flusso PKCE OAuth 2.0.
Il diagramma seguente illustra il flusso funzionale dell'applicazione a pagina singola WKND che ottiene il token di accesso specifico dell'utente per richiamare le API AEM basate su OpenAPI:
- L’applicazione a pagina singola avvia il flusso di autenticazione indirizzando l’utente al sistema Adobe Identity Management (IMS) tramite una richiesta di autorizzazione.
- Come parte della richiesta di autorizzazione, l'applicazione a pagina singola invia il client_id, redirect_uri e code_challenge a IMS, seguendo il flusso PKCE di OAuth 2.0. L'applicazione a pagina singola genera un code_verifier casuale, esegue l'hash utilizzando SHA-256 e Base64 codifica il risultato per creare la code_challenge.
- IMS autentica l'utente e, in caso di autenticazione corretta, emette un authorization_code, che viene inviato nuovamente all'applicazione a pagina singola tramite redirect_uri.
- L'applicazione a pagina singola scambia il codice_autorizzazione per un token di accesso inviando una richiesta POST all'endpoint del token IMS. Include il code_verifier nella richiesta di convalida della code_challenge inviata in precedenza. In questo modo la richiesta di autorizzazione (passaggio 2) e la richiesta di token (passaggio 4) sono collegate allo stesso flusso di autenticazione, impedendo attacchi di intercettazione.
- IMS convalida il code_verifier e restituisce il token di accesso specifico dell'utente.
- L'applicazione a pagina singola include il token di accesso nelle richieste API ad AEM per l'autenticazione e il recupero di contenuto specifico dell'utente.
L'applicazione a pagina singola WKND è un'applicazione basata su React e utilizza React Context per la gestione dello stato di autenticazione, React Router per la navigazione.
Altri framework SPA come Angular, Vue o Vanilla JavaScript possono essere utilizzati per creare SPA che si integrano con le API Adobe utilizzando gli approcci illustrati in questa esercitazione.
Come utilizzare questa esercitazione how-to-use-this-tutorial
Puoi affrontare questa esercitazione in due modi:
- Rivedi snippet di codice chiave SPA: scopri il flusso di autenticazione delle app a pagina singola OAuth ed esplora le implementazioni delle chiamate API chiave nell'applicazione a pagina singola WKND.
- Imposta ed esegui l'applicazione a pagina singola: segui le istruzioni dettagliate per configurare ed eseguire l'applicazione a pagina singola WKND nel computer locale.
Scegli il percorso che meglio si adatta alle tue esigenze!
Rivedi snippet di codice chiave SPA review-spa-key-code-snippets
Approfondiamo i frammenti di codice chiave dell’applicazione a pagina singola WKND che mostrano come:
-
Ottieni un token di accesso specifico per l’utente utilizzando il flusso di autenticazione OAuth per app a pagina singola.
-
Richiama le API AEM basate su OpenAPI direttamente dal lato client.
Questi snippet aiutano a comprendere il processo di autenticazione e le interazioni API all’interno dell’applicazione a pagina singola.
Scarica il codice SPA download-the-spa-code
-
Scarica il file zip WKND SPA & AEM API - Demo App ed estrailo.
-
Passa alla cartella estratta e apri il file
.env.example
nel tuo editor di codice preferito. Esamina i parametri di configurazione richiesti.code language-plaintext ######################################################################## # Adobe IMS, Adobe Developer Console (ADC), and AEM as a Cloud Service Information ######################################################################## # Adobe IMS OAuth endpoints REACT_APP_ADOBE_IMS_AUTHORIZATION_ENDPOINT=https://ims-na1.adobelogin.com/ims/authorize/v2 REACT_APP_ADOBE_IMS_TOKEN_ENDPOINT=https://ims-na1.adobelogin.com/ims/token/v3 # Adobe Developer Console (ADC) Project's OAuth Single-Page App credential REACT_APP_ADC_CLIENT_ID=<ADC Project OAuth Single-Page App credential ClientID> REACT_APP_ADC_SCOPES=<ADC Project OAuth Single-Page App credential Scopes> # AEM Assets Information REACT_APP_AEM_ASSET_HOSTNAME=<AEMCS Hostname, e.g., https://author-p63947-e1502138.adobeaemcloud.com/> ################################################ # Single Page Application Information ################################################ # Enable HTTPS for local development HTTPS=true PORT=3001 # SSL Certificate and Key for local development SSL_CRT_FILE=./ssl/server.crt SSL_KEY_FILE=./ssl/server.key # The URL to which the user will be redirected after the OAuth flow is complete REACT_APP_REDIRECT_URI=https://localhost:3000/callback
È necessario sostituire i segnaposto con i valori effettivi del progetto Adobe Developer Console (ADC) e dell’istanza di AEM as a Cloud Service Assets.
Autenticazione utente IMS e autorizzazione SPA ims-user-authentication-and-spa-authorization
Esaminiamo il codice che gestisce l’autenticazione utente IMS e l’autorizzazione SPA. Per recuperare i modelli per frammenti di contenuto e le cartelle DAM, l’utente deve effettuare l’autenticazione con Adobe IMS e concedere l’autorizzazione SPA WKND per accedere alle API di AEM per suo conto.
Durante l’accesso iniziale, all’utente viene richiesto di fornire il consenso, consentendo all’applicazione a pagina singola WKND di accedere in modo sicuro alle risorse richieste.
-
Nel file
src/context/IMSAuthContext.js
, la funzionelogin
avvia l'autenticazione utente IMS e il flusso di autorizzazione dell'app. Genera uncode_verifier
e uncode_challenge
casuali per scambiare in modo sicurocode
per un token di accesso.code_verifier
è archiviato nell'archivio locale per un utilizzo successivo. Come accennato in precedenza, l'applicazione a pagina singola non archivia o utilizzaclient_secret
, ne genera una al volo e la utilizza in due passaggi:authorize
etoken
richieste.code language-javascript ... const login = async () => { try { const codeVerifier = generateCodeVerifier(); const codeChallenge = generateCodeChallenge(codeVerifier); localStorage.setItem(STORAGE_KEYS.CODE_VERIFIER, codeVerifier); const params = new URLSearchParams( getAuthParams(AUTH_METHODS.S256, codeChallenge, codeVerifier) ); window.location.href = `${ APP_CONFIG.adobe.ims.authorizationEndpoint //https://ims-na1.adobelogin.com/ims/authorize/v2 }?${params.toString()}`; } catch (error) { console.error("Login initialization failed:", error); throw error; } }; ... // Generate a random code verifier export function generateCodeVerifier() { const array = new Uint8Array(32); window.crypto.getRandomValues(array); const wordArray = CryptoJS.lib.WordArray.create(array); return base64URLEncode(wordArray); } // Generate code challenge using SHA-256 export function generateCodeChallenge(codeVerifier) { const hash = CryptoJS.SHA256(codeVerifier); return base64URLEncode(hash); } // Get authorization URL parameters const getAuthParams = useCallback((method, codeChallenge, codeVerifier) => { const baseParams = { client_id: APP_CONFIG.adobe.adc.clientId, // ADC Project OAuth Single-Page App credential ClientID scope: APP_CONFIG.adobe.adc.scopes, // ADC Project OAuth Single-Page App credential Scopes response_type: "code", redirect_uri: APP_CONFIG.adobe.spa.redirectUri, // SPA redirect URI https://localhost:3000/callback code_challenge_method: method, // S256 or plain }; return { ...baseParams, code_challenge: method === AUTH_METHODS.S256 ? codeChallenge : codeVerifier, }; }, []); ...
Se l’utente non è autenticato tramite Adobe IMS, viene visualizzata la pagina di accesso di Adobe ID in cui viene richiesto all’utente di eseguire l’autenticazione.
Se è già stato autenticato, l'utente verrà reindirizzato al redirect_uri specificato dell'applicazione a pagina singola WKND con un authorization_code.
Recupero del token di accesso tramite il flusso PKCE di OAuth 2.0 access-token-retrieval-using-oauth-20-pkce-flow
L'applicazione a pagina singola WKND scambia in modo sicuro il authorization_code con Adobe IMS per un token di accesso specifico dell'utente utilizzando client_id e code_verifier.
-
Nel file
src/context/IMSAuthContext.js
, la funzioneexchangeCodeForToken
scambia il authorization_code per un token di accesso specifico dell'utente.code language-javascript ... // Handle the callback from the Adobe IMS authorization endpoint const handleCallback = async (code) => { if (authState.isProcessingCallback) return; try { updateAuthState({ isProcessingCallback: true }); const data = await exchangeCodeForToken(code); if (data.access_token) { handleStorageToken(data.access_token); localStorage.removeItem(STORAGE_KEYS.CODE_VERIFIER); } } catch (error) { console.error("Error exchanging code for token:", error); throw error; } finally { updateAuthState({ isProcessingCallback: false }); } }; ... // Exchange the authorization code for an access token const exchangeCodeForToken = useCallback(async (code) => { const codeVerifier = localStorage.getItem(STORAGE_KEYS.CODE_VERIFIER); if (!codeVerifier) { throw new Error("No code verifier found"); } //https://ims-na1.adobelogin.com/ims/token/v3 const response = await fetch(APP_CONFIG.adobe.ims.tokenEndpoint, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ grant_type: "authorization_code", client_id: APP_CONFIG.adobe.adc.clientId, // ADC Project OAuth Single-Page App credential ClientID code_verifier: codeVerifier, // Code verifier generated during login code, // Authorization code received from the IMS redirect_uri: `${window.location.origin}/callback`, }), }); if (!response.ok) { throw new Error("Token request failed"); } return response.json(); }, []); const handleStorageToken = useCallback( (token) => { if (token) { localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, token); updateAuthState({ isLoggedIn: true, accessToken: token }); } }, [updateAuthState] ); ...
Il token di accesso viene memorizzato nell’archiviazione locale del browser e utilizzato nelle chiamate API successive alle API di AEM.
Accesso alle API AEM basate su OpenAPI tramite il token di accesso accessing-openapi-based-aem-apis-using-the-access-token
L’applicazione a pagina singola WKND utilizza il token di accesso specifico dell’utente per richiamare i modelli per frammenti di contenuto e gli endpoint API per cartelle DAM.
Nel file src/components/InvokeAemApis.js
, la funzione fetchContentFragmentModels
illustra come utilizzare il token di accesso per richiamare le API AEM basate su OpenAPI dal lato client.
...
// Fetch Content Fragment Models
const fetchContentFragmentModels = useCallback(async () => {
try {
updateState({ isLoading: true, error: null });
const data = await makeApiRequest({
endpoint: `${API_PATHS.CF_MODELS}?cursor=0&limit=10&projection=summary`,
});
updateState({ cfModels: data.items });
} catch (err) {
updateState({ error: err.message });
console.error("Error fetching CF models:", err);
} finally {
updateState({ isLoading: false });
}
}, [makeApiRequest, updateState]);
// Common API request helper
const makeApiRequest = useCallback(
async ({ endpoint, method = "GET", passAPIKey = false, body = null }) => {
// Get the access token from the local storage
const token = localStorage.getItem("adobe_ims_access_token");
if (!token) {
throw new Error("No access token available. Please login again.");
}
const headers = {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
...(passAPIKey && { "x-api-key": APP_CONFIG.adobe.adc.clientId }),
};
const response = await fetch(
`${APP_CONFIG.adobe.aem.hostname}${endpoint}`,
{
method,
headers,
...(body && { body: JSON.stringify(body) }),
}
);
if (!response.ok) {
throw new Error(`API request failed: ${response.statusText}`);
}
return method === "DELETE" ? null : response.json();
},
[]
);
...
Configurare ed eseguire l’applicazione a pagina singola setup-and-run-the-spa
Configuriamo ed eseguiamo l’applicazione a pagina singola WKND sul computer locale per comprendere il flusso di autenticazione app a pagina singola OAuth e le chiamate API.
Prerequisiti prerequisites
Per completare questa esercitazione, è necessario:
-
L’ambiente AEM as a Cloud Service è stato modernizzato con:
- AEM versione
2024.10.18459.20241031T210302Z
o successiva. - Nuovi profili di prodotto (se l’ambiente è stato creato prima di novembre 2024)
Per ulteriori dettagli, consulta l'articolo Configurazione delle API AEM basate su OpenAPI.
- AEM versione
-
Il progetto WKND Sites di esempio deve essere distribuito su di esso.
-
Accesso a Adobe Developer Console.
-
Installa Node.js nel computer locale per eseguire l'applicazione NodeJS di esempio.
Passaggi di sviluppo development-steps
Le fasi di sviluppo di alto livello sono:
-
Configura progetto ADC
- Aggiungi le API Assets e Sites.
- Configura le credenziali dell'app a pagina singola OAuth.
-
Configurare l’istanza di AEM
- Per abilitare la comunicazione di un progetto ADC
- Consentire all’applicazione a pagina singola di accedere alle API di AEM configurando le impostazioni CORS.
-
Configurare ed eseguire l’applicazione a pagina singola WKND sul computer locale
-
Verificare il flusso end-to-end
Configura progetto ADC configure-adc-project
Il passaggio di configurazione del progetto ADC è repeat dalle API AEM basate su OpenAPI. Viene ripetuto per aggiungere l’API Assets e Sites e configurarne il metodo di autenticazione come app a pagina singola OAuth.
-
Da Adobe Developer Console, apri il progetto desiderato.
-
Per aggiungere le API di AEM, fai clic sul pulsante Aggiungi API.
-
Nella finestra di dialogo Aggiungi API, filtra per Experience Cloud, seleziona la scheda Gestione contenuto siti AEM CS e fai clic su Avanti.
note tip TIP Se la scheda API AEM desiderata è disabilitata e Perché è disabilitata?Le informazioni di mostrano il messaggio Licenza richiesta uno dei motivi potrebbe essere che NON hai modernizzato l'ambiente AEM as a Cloud Service. Per ulteriori informazioni, consulta Modernizzazione dell'ambiente AEM as a Cloud Service. -
Nella finestra di dialogo Configura API, selezionare l'opzione di autenticazione Autenticazione utente e fare clic su Avanti.
-
Nella prossima finestra di dialogo Configura API, seleziona l'opzione di autenticazione App a pagina singola OAuth e fai clic su Avanti.
-
Nella finestra di dialogo Configura app a pagina singola OAuth, immetti i dettagli seguenti e fai clic su Avanti.
- URI di reindirizzamento predefinito:
https://localhost:3001/callback
- Schema URI di reindirizzamento:
https://localhost:3001/callback
- URI di reindirizzamento predefinito:
-
Rivedi gli ambiti disponibili e fai clic su Salva API configurata.
-
Ripeti i passaggi precedenti per aggiungere l'API Autore AEM Assets.
-
Controlla l’API di AEM e la configurazione dell’autenticazione.
Configura istanza AEM per abilitare la comunicazione del progetto ADC configure-aem-instance-to-enable-adc-project-communication
Segui le istruzioni riportate nell'articolo Configura le API AEM basate su OpenAPI per configurare l'istanza di AEM in modo da abilitare la comunicazione con il progetto ADC.
Configurazione AEM CORS aem-cors-configuration
La condivisione CORS (Cross-Origin Resource Sharing) di AEM as a Cloud Service facilita le proprietà web non AEM nell’effettuare chiamate lato client alle API AEM basate su browser.
-
In AEM Project individuare o creare il file
com.adobe.granite.cors.impl.CORSPolicyImpl~wknd-graphql.cfg.json
dalla cartella/ui.config/src/main/content/jcr_root/apps/wknd/osgiconfig/config.author/
. -
Aggiungi la seguente configurazione al file.
code language-json { "alloworigin":[ "" ], "alloworiginregexp":[ "https://localhost:.*", "http://localhost:.*" ], "allowedpaths": [ "/adobe/sites/.*", "/graphql/execute.json.*", "/content/_cq_graphql/wknd-shared/endpoint.json", "/content/experience-fragments/.*" ], "supportedheaders": [ "Origin", "Accept", "X-Requested-With", "Content-Type", "Access-Control-Request-Method", "Access-Control-Request-Headers", "Authorization" ], "supportedmethods":[ "GET", "HEAD", "POST" ], "maxage:Integer": 1800, "supportscredentials": true, "exposedheaders":[ "" ] }
-
Apporta le modifiche alla configurazione e le invia all’archivio Git remoto a cui è connessa la pipeline Cloud Manager.
-
Distribuisci le modifiche precedenti utilizzando la pipeline FullStack in Cloud Manager.
Configurare ed eseguire l’applicazione a pagina singola configure-and-run-the-spa
-
Scarica il file zip WKND SPA & AEM API - Demo App ed estrailo.
-
Passare alla cartella estratta e copiare il file
.env.example
in.env
. -
Aggiorna il file
.env
con i parametri di configurazione richiesti dal progetto Adobe Developer Console (ADC) e dall'ambiente AEM as a Cloud Service. Ad esempio:code language-plaintext ######################################################################## # Adobe IMS, Adobe Developer Console (ADC), and AEM as a Cloud Service Information ######################################################################## # Adobe IMS OAuth endpoints REACT_APP_ADOBE_IMS_AUTHORIZATION_ENDPOINT=https://ims-na1.adobelogin.com/ims/authorize/v2 REACT_APP_ADOBE_IMS_TOKEN_ENDPOINT=https://ims-na1.adobelogin.com/ims/token/v3 REACT_APP_ADOBE_IMS_USERINFO_ENDPOINT=https://ims-na1.adobelogin.com/ims/userinfo/v2 # Adobe Developer Console (ADC) Project's OAuth Single-Page App credential REACT_APP_ADC_CLIENT_ID=ddsfs455a4a440c48c7474687c96945d REACT_APP_ADC_SCOPES=AdobeID,openid,aem.folders,aem.assets.author,aem.fragments.management # AEM Assets Information REACT_APP_AEM_ASSET_HOSTNAME=https://author-p69647-e1453424.adobeaemcloud.com/ ################################################ # Single Page Application Information ################################################ # Enable HTTPS for local development HTTPS=true PORT=3001 # SSL Certificate and Key for local development SSL_CRT_FILE=./ssl/server.crt SSL_KEY_FILE=./ssl/server.key # The URL to which the user will be redirected after the OAuth flow is complete REACT_APP_REDIRECT_URI=https://localhost:3000/callback
-
Apri un terminale e passa alla cartella estratta. Installa le dipendenze richieste e avvia l’applicazione a pagina singola WKND utilizzando il comando seguente.
code language-bash $ npm install $ npm start
Verificare il flusso end-to-end verify-the-end-to-end-flow
-
Apri un browser e passa a
https://localhost:3001
per accedere all’applicazione a pagina singola WKND. Accetta l’avviso del certificato autofirmato. -
Fai clic sul pulsante Accesso Adobe IMS per avviare il flusso di autenticazione OAuth per app a pagina singola.
-
Esegui l’autenticazione in base a Adobe IMS e fornisci il consenso per consentire all’applicazione a pagina singola WKND di accedere alle risorse per tuo conto.
-
Dopo aver eseguito correttamente l'autenticazione, si viene reindirizzati alla route
/invoke-aem-apis
dell'applicazione a pagina singola WKND e il token di accesso viene archiviato nell'archivio locale del browser. -
Dalla route
https://localhost:3001/invoke-aem-apis
, fai clic sul pulsante Recupera modelli per frammenti di contenuto per richiamare l'API Modelli per frammenti di contenuto. L’applicazione a pagina singola visualizza l’elenco dei modelli per frammenti di contenuto. -
Analogamente, nella scheda Assets - Folders API puoi elencare, creare ed eliminare cartelle DAM.
-
Negli strumenti per sviluppatori del browser, puoi esaminare le richieste e le risposte di rete per comprendere le chiamate API.
Rivedi il codice SPA review-the-spa-code
Esaminiamo la struttura del codice di alto livello e i principali punti di ingresso dell’applicazione a pagina singola WKND. L’applicazione a pagina singola viene creata utilizzando il framework React e utilizza l’API React Context per l’autenticazione e la gestione dello stato.
-
Il file
src/App.js
è il punto di ingresso principale dell'applicazione a pagina singola WKND. Il componente app esegue il wrapping dell'intera applicazione e inizializza il contestoIMSAuthProvider
. -
src/context/IMSAuthContext.js
crea Adobe IMSAuthContext per fornire lo stato di autenticazione ai componenti figlio. Include le funzioni di accesso, logout e handleCallback per avviare il flusso di autenticazione dell'app a pagina singola OAuth. -
La cartella
src/components
contiene vari componenti per dimostrare le chiamate API alle API di AEM. Il componenteInvokeAemApis.js
illustra come utilizzare il token di accesso per richiamare le API di AEM. -
Il file
src/config/config.js
carica le variabili di ambiente dal file.env
e le esporta per l'utilizzo nell'applicazione. -
Il file
src/utils/auth.js
contiene funzioni di utilità per generare il codice di validazione e il codice di autenticazione per il flusso PKCE di OAuth 2.0. -
La cartella
ssl
contiene il certificato autofirmato e i file chiave per eseguire il proxy HTTP SSL locale.
Puoi sviluppare o integrare l’applicazione a pagina singola esistente con le API di Adobe utilizzando gli approcci illustrati in questa esercitazione.
Riepilogo summary
In questo tutorial, hai imparato a richiamare le API AEM basate su OpenAPI su AEM as a Cloud Service utilizzando l’autenticazione basata sull’utente da un’app a pagina singola (SPA) tramite il flusso PKCE OAuth 2.0.