Службы торгов и аукционов (B&A) — это набор услуг для покупателей и продавцов рекламы, который работает в доверенной среде исполнения (TEE) для облегчения аукциона с защищенной аудиторией (PA). В этом руководстве разработчика объясняется, как продавец может интегрировать аукцион Chrome PA для B&A.
Прохождение
Эти шаги можно резюмировать следующим образом:
- Вызовите
getInterestGroupAdAuctionData()
чтобы получить зашифрованные полезные данные из браузера. - Вызовите
fetch('https://your-ad-server.example')
и отправьте запрос единого аукциона с зашифрованными полезными данными на свой SAS. - Вызовите операцию
SelectAd()
вашего SFE из вашего SAS, чтобы запустить аукцион B&A. - Верните на страницу результат аукциона B&A вместе с хешем ответа.
- Вызовите
runAdAuction()
в браузере, чтобы запустить аукцион PA с одним, смешанным или несколькими продавцами, и передайте результат аукциона B&A на стороне сервера в вызов.
Получите зашифрованные данные аукциона рекламы
Чтобы получить данные, необходимые для запуска аукциона B&A на стороне сервера, код JavaScript продавца на странице издателя вызывает navigator.getInterestGroupAdAuctionData()
.
const adAuctionData = await navigator.getInterestGroupAdAuctionData({
seller: 'https://ssp.example', // Required
requestSize: 51200,
coordinatorOrigin: 'https://publickeyservice.pa.gcp.privacysandboxservices.com/',
perBuyerConfig: {
'https://dsp-x.example': { targetSize: 8192 },
'https://dsp-y.example': { targetSize: 8192 }
}
});
const { requestId, request } = adAuctionData;
Поле | Описание |
---|---|
seller | Необходимый . Происхождение продавца, проводящего аукцион. Это значение должно совпадать со значением seller в вызове runAdAuction() позже. |
requestSize | Необязательный . Устанавливает максимальный размер полезных данных всех данных о покупателях. Дополнительную информацию см. в разделе «Размер запроса » пояснения. |
perBuyerConfig | Необязательный . Устанавливает конфигурации для каждого покупателя, а также контролирует, какие покупатели участвуют в аукционе B&A. Если происхождение покупателя указано в |
targetSize | Необязательно, если установлен requestSize . Требуется , если в perBuyerConfig указано происхождение покупателя, но не задан requestSize .Устанавливает максимальный размер полезной нагрузки данных этого покупателя. Дополнительную информацию см. в разделе «Размер запроса » пояснения. |
coordinatorOrigin | Необязательно , но со временем станет обязательным. По умолчанию используется https://publickeyservice.pa.gcp.privacysandboxservices.com если не установлено.Устанавливает координатора, который будет использоваться для получения ключа для шифрования полезных данных. Дополнительную информацию см. в разделе «Координатор» пояснения. |
При выполнении вызова браузер считывает группы интересов покупателей, перечисленных в perBuyerConfig
, и шифрует данные покупателя. Эти данные покупателя содержат межсайтовую информацию, которая будет использоваться для ставок, и не могут быть расшифрованы вне TEE. Для оптимизации полезных данных в полезные данные включаются только название группы интересов, ключи доверенных сигналов назначения ставок и сигналы браузера.
В объекте данных аукциона рекламы, возвращаемом вызовом getInterestGroupAdAuctionData()
, доступна строка requestId
и зашифрованный массив байтов request
.
Строка requestId
используется позже, когда вызывается runAdAuction()
для завершения аукциона в браузере. Зашифрованная полезная нагрузка request
отправляется в рекламную службу продавца как часть единого запроса аукциона.
Пример этого вызова можно увидеть в коде JavaScript продавца локального приложения для тестирования .
Отправьте единый запрос на аукцион в SAS.
Единый запрос аукциона — это запрос, который содержит полезные данные контекстного аукциона в виде открытого текста и полезные данные аукциона PA B&A. Полезная нагрузка аукциона PA B&A — это зашифрованные данные request
, сгенерированные браузером при вызове getInterestGroupAdAuctionData()
. Этот запрос отправляется в SAS, где организуются контекстный аукцион и аукцион PA B&A.
fetch('https://ssp.example/ad-auction', {
method: 'POST',
adAuctionHeaders: true,
body: JSON.stringify({
contextualAuctionPayload: { somePayload },
protectedAudienceAuctionPayload: encodeBinaryData(request)
}),
});
Чтобы отправить запрос в SAS, со страницы выполняется вызов fetch()
:
- Вызов должен включать параметр
adAuctionHeaders: true
, который сигнализирует браузеру о необходимости проверить ответ на этот вызов позднее, когда будет вызванrunAdAuction()
для завершения аукциона в браузере. - Источник запроса на выборку должен совпадать с источником происхождения
seller
, указанным в вызовахgetInterestGroupAdAuctionData()
иrunAdAuction()
.
Тело вызова содержит:
- Полезная нагрузка контекстного аукциона в виде открытого текста, которая будет использоваться SAS для запуска контекстного аукциона.
- Зашифрованная полезная нагрузка аукциона Protected Audience, которая будет отправлена в SFE компанией SAS для проведения серверного аукциона B&A.
Пример этого вызова можно увидеть в коде JavaScript продавца локального приложения для тестирования .
Кодирование и декодирование Base64
Зашифрованные полезные данные request
, возвращаемые из вызова getInterestGroupAdAuctionData()
являются экземпляром Uint8Array
, который является типом данных, который JSON не может обработать. Чтобы отправить массив байтов в формате JSON, вы можете применить кодировку base64 к двоичным данным, чтобы преобразовать их в строку.
API браузера JavaScript предоставляет функции atob()
и btoa()
в window
, которые преобразуют двоичные данные в строку ASCII в кодировке Base64. ( atob
означает преобразование ASCII в двоичный код, а btoa
означает преобразование двоичного кода в ASCII).
Вызов btoa()
для кодирования двоичных данных в строку в кодировке Base64 выглядит следующим образом:
function encodeBinaryData(data) {
return btoa(String.fromCharCode.apply(null, data));
}
Зашифрованный результат аукциона B&A, возвращаемый этим fetch
выборки, также имеет кодировку Base64, поэтому вам необходимо декодировать его обратно в двоичные данные. Вызовите atob()
для декодирования строки ASCII в кодировке Base64 в двоичные данные:
function decodeBase64String(base64string) {
return new Uint8Array(
atob(base64string)
.split('')
.map((char) => char.charCodeAt(0))
);
}
Однако строка в кодировке Base64 обычно примерно на 33% больше исходных данных. Если вы хотите еще больше улучшить задержку, используйте для отправки двоичных данных формат, отличный от JSON.
Позвоните в SelectAd
SFE, чтобы провести аукцион B&A.
Как только служба объявлений продавца получает запрос на единый аукцион со страницы, сначала запускается контекстный аукцион, чтобы определить победителя контекстного аукциона и собрать сигналы покупателя, которые будут переданы на аукцион PA B&A. Затем аукцион B&A инициируется путем вызова операции SelectAd
SFE из SAS с полезной нагрузкой запроса. Обратите внимание, что некоторые метаданные из запроса страницы к SAS на шаге 2 пересылаются в SFE.
Создайте полезную нагрузку SelectAdRequest
Полезная нагрузка запроса вызова SelectAd
может быть построена следующим образом:
const selectAdRequest = {
auction_config: {
seller: 'https://ssp.example',
auction_signals: '{"testKey":"someValue"}',
seller_signals: '{"testKey":"someValue"}',
buyer_list: [
'https://dsp-x.example',
'https://dsp-y.example',
],
per_buyer_config: {
'https://dsp-x.example': { buyer_signals: '{"testKey": "someValue"}' },
'https://dsp-y.example': { buyer_signals: '{"testKey": "someValue"}' },
},
},
client_type: 'CLIENT_TYPE_BROWSER',
protected_auction_ciphertext: decodeBase64string(request)
};
Обратите внимание: если зашифрованные данные рекламного аукциона из браузера были закодированы в формате Base64, их необходимо декодировать обратно в двоичные данные , если запрос к SFE отправляется с использованием gRPC. Если запрос отправляется по протоколу HTTP, зашифрованные данные аукциона рекламы могут оставаться в форме, закодированной в формате Base64.
Чтобы увидеть другие поля, определенные в запросе SelectAd
, см. прототип определения SelectAdRequest
.
Установите поле продавца верхнего уровня для смешанных аукционов и аукционов компонентов.
Если продавец проводит аукцион смешанного режима или участвует в аукционе с несколькими продавцами в качестве продавца компонентов, в запросе необходимо определить поле top_level_seller
.
Если вы продавец смешанного режима, значение top_level_seller
указывает на ваше происхождение:
const selectAdRequest = {
auction_config: {
seller: 'https://ssp-mix.example',
top_level_seller: 'https://ssp-mix.example',
}
}
Если вы являетесь продавцом компонентов, значение top_level_seller
— это продавец верхнего уровня на аукционе с несколькими продавцами:
const selectAdRequest = {
auction_config: {
seller: 'https://ssp-mix.example',
top_level_seller: 'https://ssp-top.example',
}
}
Позвоните SelectAd
SFE
Вызов SFE из SAS можно выполнить с помощью gRPC или HTTP.
вызов gRPC
Запрос gRPC к SFE выглядит следующим образом при использовании Express в узле с клиентом gRPC :
import grpc from '@grpc/grpc-js';
// Load proto definition
const packageDefinition = protoLoader.loadSync(protoPath, { keepCase: true, enums: String });
const {
privacy_sandbox: {
bidding_auction_servers: { SellerFrontEnd }
}
} = grpc.loadPackageDefinition(packageDefinition);
// Instantiate the gRPC client
const sfeGrpcClient = new SellerFrontEnd('192.168.84.104:50067', grpc.credentials.createInsecure());
// Send SelectAd request
sfeGrpcClient.selectAd(selectAdRequest,(error, response) => {
// Handle SFE response
});
Определение прототипа для клиента SFE можно найти в локальном репозитории приложения для тестирования .
HTTP-вызов прокси-сервера Envoy
HTTP-запрос POST к SFE отправляется по пути /v1/selectAd
и выглядит следующим образом:
fetch('https://ssp-ba.example/sfe/v1/selectAd', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(selectAdRequest),
});
Переслать метаданные
Следующие метаданные из вызова страницы в SAS должны быть добавлены в вызов SAS SelectAd
в SFE:
-
Accept-Language
-
User-Agent
- IP-адрес
Когда метаданные отправляются в SFE, они должны использовать следующие нестандартные заголовки, поскольку gRPC может изменить заголовок User-Agent
:
-
X-Accept-Language
-
X-User-Agent
-
X-BnA-Client-IP
Ниже приведен пример того, как метаданные можно пересылать с помощью Express in Node с клиентом gRPC :
sellerAdService.post('/ad-auction', (req, res) => {
// …
const metadata = new grpc.Metadata();
metadata.add('X-Accept-Language', req.header('Accept-Language'));
metadata.add('X-User-Agent', req.header('User-Agent'));
metadata.add('X-BnA-Client-IP', req.ip);
const sfeGrpcClient = createSfeGrpcClient();
sfeGrpcClient.selectAd(selectAdRequest, metadata, callbackFn);
})
Ниже приведен пример того, как метаданные могут быть перенаправлены с помощью HTTP-вызова:
sellerAdService.post('/ad-auction', (req, res) => {
// …
fetch('https://ssp-ba.example/sfe/v1/selectAd', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Accept-Language': req.header('Accept-Language'),
'X-User-Agent': req.header('User-Agent'),
'X-BnA-Client-IP': req.ip
},
body: JSON.stringify(selectAdRequest)
});
})
Аукцион с участием нескольких продавцов, управляемый сервером
Если вы являетесь продавцом верхнего уровня, проводящим аукцион с несколькими продавцами, управляемый сервером , вызов GetComponentAuctionCiphertexts
выполняется в SFE до выполнения вызова SelectAd
. Ответ содержит повторно зашифрованные полезные данные аукциона компонентов, которые отправляются в рекламные службы продавца компонентов. Возвращенные результаты рекламного аукциона компонентов B&A передаются в вызов SelectAd
SFE продавца верхнего уровня.
Дополнительную информацию см . в пояснении к мультипродавцам на GitHub.
Вернуть результат аукциона B&A на страницу
После завершения аукциона B&A зашифрованный результат аукциона возвращается в SAS, и SAS отвечает на запрос единого аукциона со страницы на шаге 2 с зашифрованным результатом аукциона. В ответе SAS на страницу хеш SHA-256 в кодировке Base64url зашифрованного результата аукциона устанавливается в заголовке ответа Ad-Auction-Result
. Этот хэш используется браузером для проверки полезной нагрузки при завершении аукциона в клиенте.
Создание хеша SHA-256 с кодировкой base64 в Node выглядит следующим образом:
import { createHash } from 'crypto';
createHash('sha256')
.update(binaryData, 'base64')
.digest('base64url');
Прикрепление хэша в заголовке ответа и возврат результата аукциона на страницу выглядит следующим образом:
sellerAdService.post('/ad-auction', (req, res) => {
// …
sfeGrpcClient.selectAd(selectAdRequest, metadata, (error, response) => {
const { auction_result_ciphertext } = response;
const ciphertextShaHash = createHash('sha256')
.update(auction_result_ciphertext, 'base64')
.digest('base64url');
res.set('Ad-Auction-Result', ciphertextShaHash);
res.json({
protectedAudienceAuctionResult: encodeBinaryData(auction_result_ciphertext),
contextualAuctionResult: getContextualAuctionResult()
});
});
})
Поскольку это ответ на запрос единого аукциона, сделанный со страницы на шаге 2 , в ответ также включается результат контекстного аукциона.
В Ad-Auction-Result
можно включить несколько хешей, повторяя заголовок или разделяя хэши. Следующие два заголовка ответа эквивалентны:
Ad-Auction-Result: ungWv48Bz-pBQUDeXa4iI7ADYaOWF3qctBD_YfIAFa0=,9UTB-u-WshX66Xqz5DNCpEK9z-x5oCS5SXvgyeoRB1k=
Ad-Auction-Result: ungWv48Bz-pBQUDeXa4iI7ADYaOWF3qctBD_YfIAFa0=
Ad-Auction-Result: 9UTB-u-WshX66Xqz5DNCpEK9z-x5oCS5SXvgyeoRB1k=
Пример этого вызова можно увидеть в коде сервера продавца локального приложения для тестирования .
Вызовите runAdAuction()
чтобы завершить аукцион.
Ответ на единый аукцион, возвращенный из SAS, включает зашифрованный результат аукциона B&A. Эта полезная нагрузка передается в вызов runAdAuction()
для завершения аукциона в браузере. Значение requestId
из вызова getInterestGroupAdAuctionData()
на шаге 1 также передается на аукцион.
// Get the encrypted ad auction data (Step #1)
const { requestId, request } = navigator.getInterestGroupAdAuctionData(adAuctionDataConfig)
// Send unified auction request (Step #2)
const response = await fetch('https://ssp-ba.example/ad-auction', {
method: 'POST',
body: JSON.stringify({
adAuctionRequest: encodeBinaryData(request),
}),
});
const { protectedAudienceAuctionResult } = await response.json();
// Finish the auction in the browser
await navigator.runAdAuction({
// pass in "requestId" and "protectedAudienceAuctionResult"
// the config structure will differ based on the auction configuration
});
Структура конфигурации аукциона, передаваемая в вызов runAdAuction()
различается в зависимости от конфигурации аукциона, выбранной продавцом.
Аукцион с одним продавцом
Для проведения аукциона B&A с одним продавцом конфигурация аукциона вызова runAdAuction()
строится следующим образом:
await navigator.runAdAuction({
seller: 'https://ssp-ba.example',
requestId,
serverResponse: protectedAudienceAuctionResult,
});
Поле requestId
принимает requestId
, возвращаемый вызовом getInterestGroupAdAuctionData()
. Поле serverResponse
принимает массив байтов аукциона B&A, который проводился на шаге №3 .
Пример этого вызова можно увидеть в коде JavaScript продавца локального приложения для тестирования .
Смешанный аукцион
Для проведения аукциона B&A в смешанном режиме, в котором могут участвовать как покупатели на устройстве, так и покупатели B&A, конфигурация аукциона вызова runAdAuction()
строится следующим образом:
await navigator.runAdAuction({
seller: 'https://ssp-mix.example',
decisionLogicURL: 'https://ssp-mix.example/score-ad.js',
componentAuctions: [
// B&A auction result
{
seller: 'https://ssp-mix.example',
requestId,
serverResponse: protectedAudienceAuctionResult,
},
// On-device auction config
{
seller: 'https://ssp-mix.example',
decisionLogicURL: 'https://ssp-mix.example/on-device-score-ad.js',
interestGroupBuyers: [
'https://dsp-a.example', // On-device buyer
'https://dsp-a.example', // On-device buyer
],
},
]
});
Для облегчения проведения аукциона в смешанном режиме результаты аукциона B&A и конфигурация аукциона на устройстве передаются в componentAuctions
. На аукционе смешанного режима стоимость seller
одинакова как для конфигурации верхнего уровня, так и для конфигурации компонента.
Пример этого вызова можно увидеть в коде JavaScript продавца локального приложения для тестирования .
Аукцион с несколькими продавцами
Если вы являетесь продавцом высшего уровня и проводите аукцион с несколькими продавцами, организованный устройством, то каждый продавец компонентов отправляет результаты своего аукциона B&A и конфигурации аукциона на устройстве.
await navigator.runAdAuction({
seller: 'https://ssp-top.example',
decisionLogicURL: 'https://ssp-top.example/score-ad.js',
componentAuctions: [
// SSP-BA's B&A-only auction result
{
seller: 'https://ssp-ba.example',
requestId: 'g8312cb2-da2d-4e9b-80e6-e13dec2a581c',
serverResponse: Uint8Array(560) [193, 120, 4, …] // Encrypted B&A auction result
},
// SSP-MIX's B&A auction result
{
seller: 'https://ssp-mix.example',
requestId: 'f5135cb2-da2d-4e9b-80e6-e13dec2a581c',
serverResponse: Uint8Array(560) [133, 20, 4, …] // Encrypted B&A auction result
}.
// SSP-MIX's on-device auction config
{
seller: 'https://ssp-mix.example',
interestGroupBuyers: ['https://dsp-a.example', 'https://dsp-b.example'],
decisionLogicURL: 'https://ssp-mix.example/score-ad.js',
}
// SSP-OD's on-device auction config
{
seller: 'https://ssp-od.example',
interestGroupBuyers: ['https://dsp-a.example', 'https://dsp-b.example'],
decisionLogicURL: 'https://ssp-od.example/score-ad.js',
}
]
})
Пример этого вызова можно увидеть в коде JavaScript продавца локального приложения для тестирования .
Следующие шаги
Прочитав это руководство, вы можете предпринять следующие шаги:
Узнать больше
- Для более глубокого понимания см. следующие пояснения на GitHub:
- Узнайте больше об архитектуре B&A для Интернета.
- Поэкспериментируйте с защищенной аудиторией с помощью B&A, следуя кодовой лаборатории «Сквозное локальное тестирование» .
Есть вопросы?
- Если у вас есть вопрос об услугах по проведению торгов и аукционов, откройте его в репозитории B&A Services .
- Если у вас есть вопросы о Privacy Sandbox в целом, откройте вопрос в репозитории Privacy-sandbox-dev-support .