A integração do Adobe Experience Manager (AEM) Sites com o Adobe Experience Platform (AEP) exige que o AEM gere e mantenha um cookie exclusivo de ID de dispositivo primário (FPID) para rastrear exclusivamente a atividade do usuário.
Leia a documentação de suporte para saiba mais sobre os detalhes de como as IDs de dispositivo de primeira parte e as IDs de Experience Cloud funcionam juntas.
Abaixo está uma visão geral de como os FPIDs funcionam ao usar o AEM como host da Web.
O serviço de publicação do AEM otimiza o desempenho, armazenando solicitações em cache o máximo possível, nos caches do Dispatcher para CDN e AEM.
As solicitações HTTP imperativas que geram o cookie FPID único por usuário e retornam o valor FPID nunca são armazenadas em cache e fornecidas diretamente do AEM Publish, que pode implementar lógica para garantir a exclusividade.
Evite gerar o cookie FPID em solicitações de páginas da Web ou outros recursos armazenáveis em cache, pois a combinação do requisito de exclusividade do FPID tornaria esses recursos não armazenáveis em cache.
O diagrama a seguir descreve como o AEM Publish Service gerencia FPIDs.
O código e a configuração a seguir podem ser implantados no serviço de publicação do AEM para criar um terminal que gera ou estende a vida útil de um cookie FPID existente e retorna o FPID como JSON.
Um endpoint HTTP AEM deve ser criado para gerar ou estender um cookie FPID, usando um Servlet Sling.
/bin/aem/fpid
como, a autenticação não é necessária para acessá-lo. Se a autenticação for necessária, associe a um tipo de recurso do Sling.Cache-Control: no-store
para evitar o armazenamento em cache, mas esse endpoint também deve ser solicitado usando parâmetros de consulta exclusivos de eliminação de cache.Quando uma solicitação HTTP atinge o servlet, o servlet verifica se existe um cookie FPID na solicitação:
O servlet grava o FPID na resposta como um objeto JSON no formato: { fpid: "<FPID VALUE>" }
.
É importante fornecer o FPID ao cliente no corpo, pois o cookie FPID está marcado HttpOnly
, o que significa que somente o servidor pode ler seu valor, e o JavaScript do lado do cliente não.
O valor FPID do corpo da resposta é usado para parametrizar chamadas usando o SDK da Web da plataforma.
Abaixo está o código de exemplo de um endpoint de servlet AEM (disponível via HTTP GET /bin/aep/fpid
) que gera ou atualiza um cookie FPID e retorna o FPID como 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());
}
}
Um JavaScript personalizado do lado do cliente deve ser adicionado à página para chamar de forma assíncrona o servlet, gerando ou atualizando o cookie FPID e retornando o FPID na resposta.
Normalmente, esse script JavaScript é adicionado à página usando um dos seguintes métodos:
A chamada XHR para o servlet FPID AEM personalizado é rápida, embora assíncrona, portanto, é possível que um usuário visite uma página da Web fornecida pelo AEM e saia antes que a solicitação seja concluída.
Se isso ocorrer, o mesmo processo tentará novamente no próximo carregamento de página de uma página da Web a partir do AEM.
O GET HTTP para o servlet AEM FPID (/bin/aep/fpid
) é parametrizado com um parâmetro de consulta aleatório para garantir que qualquer infraestrutura entre o navegador e o serviço de Publicação do AEM não armazene a resposta da solicitação em cache.
Do mesmo modo, a Cache-Control: no-store
o cabeçalho da solicitação é adicionado para oferecer suporte à prevenção de armazenamento em cache.
Após invocação do servlet FPID AEM, o FPID é recuperado da resposta JSON e usado pelo SDK da Web da Platform para enviá-lo para APIs Experience Platform.
Consulte a documentação do Experience Platform para obter mais informações sobre uso de FPIDs no 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>
Por fim, as solicitações HTTP GET para o servlet FPID personalizado devem ser permitidas por meio do AEM do Dispatcher filter.any
configuração.
Se essa configuração do Dispatcher não for implementada corretamente, o HTTP GET solicitará /bin/aep/fpid
resulta em um 404.
dispatcher/src/conf.dispatcher.d/filters/filters.any
/1099 { /type "allow" /method "GET" /url "/bin/aep/fpid" }
Consulte a documentação do Experience Platform a seguir para IDs de dispositivo primário (FPIDs) e gerenciamento de dados de identidade com o SDK da Web da plataforma.