L’integrazione di Adobe Experience Manager (AEM) con Adobe Experience Platform (AEP) richiede che l’AEM generi e mantenga un cookie FPID (first party device ID) univoco per poter tenere traccia in modo univoco dell’attività dell’utente.
Leggere la documentazione di supporto per scopri i dettagli della collaborazione tra gli ID dispositivo di prima parte e gli ID Experience Cloud.
Di seguito è riportata una panoramica del funzionamento degli FPID quando si utilizza l’AEM come host web.
Il servizio di pubblicazione AEM ottimizza le prestazioni memorizzando nella cache le richieste il maggior numero possibile di richieste, sia nella cache CDN che in quella del Dispatcher AEM.
Le richieste HTTP imperative che generano il cookie FPID univoco per utente e restituiscono il valore FPID non vengono mai memorizzate nella cache e vengono gestite direttamente da AEM Publish, che può implementare una logica per garantire l’univocità.
Evita di generare il cookie FPID nelle richieste di pagine web o di altre risorse memorizzabili in cache, in quanto la combinazione dei requisiti di univocità dell’FPID renderebbe queste risorse non memorizzabili in cache.
Il diagramma seguente descrive come AEM Publish Service gestisce gli FPID.
Il codice e la configurazione seguenti possono essere distribuiti al servizio di pubblicazione AEM per creare un endpoint che genera o estende la durata di un cookie FPID esistente e restituisce l’FPID come JSON.
È necessario creare un endpoint HTTP AEM per generare o estendere un cookie FPID, utilizzando un Servlet Sling.
/bin/aem/fpid
poiché per accedervi non è necessaria l’autenticazione. Se è richiesta l’autenticazione, effettua un binding a un tipo di risorsa Sling.Cache-Control: no-store
per evitare il caching, ma questo endpoint deve essere richiesto utilizzando anche parametri di query univoci per il busting della cache.Quando una richiesta HTTP raggiunge il servlet, quest’ultimo controlla se nella richiesta esiste un cookie FPID:
Il servlet scrive quindi l’FPID nella risposta come oggetto JSON nel formato: { fpid: "<FPID VALUE>" }
.
È importante fornire l’FPID al client nel corpo, poiché il cookie FPID è contrassegnato HttpOnly
, il che significa che solo il server può leggerne il valore, mentre JavaScript lato client non può.
Il valore FPID dal corpo della risposta viene utilizzato per parametrizzare le chiamate utilizzando Platform Web SDK.
Di seguito è riportato un esempio di codice di un endpoint servlet AEM (disponibile tramite HTTP GET /bin/aep/fpid
) che genera o aggiorna un cookie FPID e restituisce l’FPID come JSON.
core/src/main/java/com/adobe/aem/guides/wkndexamples/core/aep/impl/FpidServlet.java
package com.adobe.aem.guides.wkndexamples.core.aep.impl;
import com.google.gson.JsonObject;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.Servlet;
import javax.servlet.http.Cookie;
import java.io.IOException;
import java.util.UUID;
import static org.apache.sling.api.servlets.ServletResolverConstants.SLING_SERVLET_PATHS;
import static org.apache.sling.api.servlets.ServletResolverConstants.SLING_SERVLET_METHODS;
@Component(
service = {Servlet.class},
property = {
SLING_SERVLET_PATHS + "=/bin/aep/fpid",
SLING_SERVLET_METHODS + "=GET"
}
)
public class FpidServlet extends SlingAllMethodsServlet {
private static final Logger log = LoggerFactory.getLogger(FpidServlet.class);
private static final String COOKIE_NAME = "FPID";
private static final String COOKIE_PATH = "/";
private static final int COOKIE_MAX_AGE = 60 * 60 * 24 * 30 * 13;
private static final String JSON_KEY = "fpid";
@Override
protected final void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
// Try to get an existing FPID cookie, this will give us the user's current FPID if it exists
final Cookie existingCookie = request.getCookie(COOKIE_NAME);
String cookieValue;
if (existingCookie == null) {
// If no FPID cookie exists, Create a new FPID UUID
cookieValue = UUID.randomUUID().toString();
} else {
// If a FPID cookie exists. get its FPID UUID so it's life can be extended
cookieValue = existingCookie.getValue();
}
// Add the newly generate FPID value, or the extended FPID value to the response
// Use addHeader(..), as we need to set SameSite=Lax (and addCoookie(..) does not support this)
response.addHeader("Set-Cookie",
COOKIE_NAME + "=" + cookieValue + "; " +
"Max-Age=" + COOKIE_MAX_AGE + "; " +
"Path=" + COOKIE_PATH + "; " +
"HttpOnly; " +
"Secure; " +
"SameSite=Lax");
// Avoid caching the response in any cache
response.addHeader("Cache-Control", "no-store");
// Since the FPID is HttpOnly, JavaScript cannot read it (only the server can)
// Write the FPID to the response as JSON so client JavaScript can access it.
final JsonObject json = new JsonObject();
json.addProperty(JSON_KEY, cookieValue);
// The JSON `{ fpid: "11111111-2222-3333-4444-55555555" }` is returned in the response
response.setContentType("application/json");
response.getWriter().write(json.toString());
}
}
È necessario aggiungere alla pagina un JavaScript lato client personalizzato per richiamare in modo asincrono il servlet, generando o aggiornando il cookie FPID e restituendo l’FPID nella risposta.
Questo script JavaScript viene in genere aggiunto alla pagina utilizzando uno dei seguenti metodi:
La chiamata XHR al servlet FPID dell’AEM personalizzato è veloce, anche se asincrona, quindi è possibile per un utente visitare una pagina web servita dall’AEM e spostarsi prima che la richiesta possa essere completata.
In questo caso, lo stesso processo tenterà di nuovo al successivo caricamento di una pagina web da AEM.
Il GET HTTP al servlet FPID dell’AEM (/bin/aep/fpid
) è parametrizzato con un parametro di query casuale per garantire che qualsiasi infrastruttura tra il browser e il servizio AEM Publish non memorizzi la risposta della richiesta nella cache.
Analogamente, il Cache-Control: no-store
viene aggiunta un’intestazione di richiesta per supportare l’evitazione del caching.
In seguito a una chiamata del servlet dell’FPID dell’AEM, l’FPID viene recuperato dalla risposta JSON e utilizzato dal Platform Web SDK per inviarlo alle API Experience Platform.
Per ulteriori informazioni su, consulta la documentazione di Experience Platform. utilizzo degli FPID in identityMap
...
<script>
// Invoke the AEM FPID servlet, and then do something with the response
fetch(`/bin/aep/fpid?_=${new Date().getTime() + '' + Math.random()}`, {
method: 'GET',
headers: {
'Cache-Control': 'no-store'
}
})
.then((response) => response.json())
.then((data) => {
// Get the FPID from JSON returned by AEM's FPID servlet
console.log('My FPID is: ' + data.fpid);
// Send the `data.fpid` to Experience Platform APIs
});
</script>
Infine, le richieste HTTP di GET al servlet FPID personalizzato devono essere consentite tramite il dispatcher dell’AEM filter.any
configurazione.
Se questa configurazione di Dispatcher non viene implementata correttamente, il GET HTTP richiede a /bin/aep/fpid
si ottiene un 404.
dispatcher/src/conf.dispatcher.d/filters/filters.any
/1099 { /type "allow" /method "GET" /url "/bin/aep/fpid" }
Consulta la seguente documentazione di Experience Platform per gli ID dispositivo di prime parti (FPID) e per la gestione dei dati di identità con Platform Web SDK.