سرویسهای پیشنهاد قیمت و حراج (B&A) مجموعهای از خدمات برای خریداران و فروشندگان تبلیغات است که در یک محیط اجرای مطمئن (TEE) اجرا میشود تا حراج مخاطبان محافظتشده (PA) را تسهیل کند. این راهنمای توسعهدهندگان توضیح میدهد که چگونه یک فروشنده میتواند برای B&A با یک حراج Chrome PA ادغام شود.
پیاده روی

مراحل را میتوان به صورت زیر خلاصه کرد:
- برای دریافت payload رمزگذاری شده از مرورگر،
getInterestGroupAdAuctionData()را فراخوانی کنید. - فراخوانی
fetch('https://your-ad-server.example')و ارسال درخواست حراج یکپارچه به همراه محتوای رمزگذاری شده به SAS شما - برای اجرای حراج B&A، از SAS خود، عملیات
SelectAd()مربوط به SFE خود را فراخوانی کنید. - نتیجه حراج B&A را به همراه هش پاسخ به صفحه برگردانید.
- برای اجرای حراج PA تک فروشندهای، حالت ترکیبی یا چند فروشندهای، تابع
runAdAuction()را در مرورگر فراخوانی کنید و نتیجه حراج B&A سمت سرور را به این فراخوانی ارسال کنید.
دادههای حراج تبلیغات رمزگذاریشده را دریافت کنید

برای دریافت دادههای مورد نیاز برای اجرای حراج B&A سمت سرور، کد جاوا اسکریپت فروشنده در صفحه ناشر، تابع 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 رمزگذاری شده به عنوان بخشی از درخواست حراج یکپارچه به سرویس تبلیغات فروشنده ارسال میشود.
برای دیدن نمونهای از این فراخوانی، به کد جاوا اسکریپت فروشنده مربوط به برنامه آزمایشی محلی مراجعه کنید.
درخواست حراج یکپارچه را به 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 برای اجرای حراج متنی استفاده شود.
- بار داده رمزگذاری شده حراج مخاطبان محافظتشده که قرار است توسط SAS به SFE ارسال شود تا حراج B&A سمت سرور اجرا شود.
برای دیدن نمونهای از این فراخوانی، به کد جاوا اسکریپت فروشنده مربوط به برنامه آزمایشی محلی مراجعه کنید.
رمزگذاری و رمزگشایی Base64
request رمزگذاریشدهای که از فراخوانی getInterestGroupAdAuctionData() برگردانده میشود، نمونهای از Uint8Array است که نوع دادهای است که JSON نمیتواند آن را مدیریت کند. برای ارسال آرایه بایت در قالب JSON، میتوانید یک کدگذاری base64 را به دادههای دودویی اعمال کنید تا آن را به یک رشته تبدیل کنید.
رابط برنامهنویسی کاربردی مرورگر جاوااسکریپت، توابع 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 است، بنابراین باید آن را به دادههای دودویی رمزگشایی کنید. برای رمزگشایی رشته ASCII کدگذاری شده base64 به دادههای دودویی، atob() را فراخوانی کنید:
function decodeBase64String(base64string) {
return new Uint8Array(
atob(base64string)
.split('')
.map((char) => char.charCodeAt(0))
);
}
با این حال، یک رشته کدگذاری شده با base64 معمولاً حدود 33٪ بزرگتر از داده اصلی است. اگر میخواهید تأخیر بیشتری داشته باشید، از قالبی غیر از JSON برای ارسال دادههای دودویی استفاده کنید.
برای اجرای حراج B&A با SelectAd از SFE تماس بگیرید

به محض اینکه سرویس تبلیغات فروشنده، درخواست حراج یکپارچه را از صفحه دریافت کرد، ابتدا حراج زمینهای اجرا میشود تا برنده حراج زمینهای مشخص شود و سیگنالهای خریدار برای ارسال به حراج PA B&A جمعآوری شوند. سپس، حراج B&A با فراخوانی عملیات SelectAd مربوط به SFE از SAS با درخواست payload آغاز میشود. توجه داشته باشید که برخی از فرادادههای درخواست صفحه به SAS در مرحله ۲ به 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 در Node و با یک کلاینت 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 باید به فراخوانی SelectAd از SAS به SFE اضافه شوند:
-
Accept-Language -
User-Agent - آدرس آیپی
وقتی فرادادهها به SFE ارسال میشوند، باید از هدرهای غیر استاندارد زیر استفاده کنند زیرا gRPC ممکن است هدر User-Agent را تغییر دهد:
-
X-Accept-Language -
X-User-Agent -
X-BnA-Client-IP
در زیر مثالی از نحوه ارسال متادیتا با استفاده از Express در 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 قبل از فراخوانی SelectAd به SFE انجام میشود. پاسخ شامل payloadهای حراج کامپوننت رمزگذاریشده مجدد است که به سرویسهای تبلیغاتی فروشنده کامپوننت ارسال میشوند. نتایج حراج تبلیغاتی B&A کامپوننت بازگردانده شده به فراخوانی SelectAd از SFE فروشنده سطح بالا ارائه میشود.
برای کسب اطلاعات بیشتر، به توضیح چندفروشندگی در گیتهاب مراجعه کنید.
نتیجه حراج B&A را به صفحه برگردانید

پس از پایان حراج B&A، نتیجه حراج رمزگذاری شده به SAS بازگردانده میشود و SAS به درخواست حراج یکپارچه از صفحه در مرحله ۲ با نتیجه حراج رمزگذاری شده پاسخ میدهد. در پاسخ 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()
});
});
})
از آنجایی که این پاسخی به درخواست حراج یکپارچه است که از صفحه مرحله ۲ ارسال شده است، نتیجه حراج زمینهای نیز در پاسخ گنجانده شده است.
با تکرار هدر یا جدا کردن هشها، میتوان چندین هش را در 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 است. این payload برای پایان دادن به حراج در مرورگر به فراخوانی runAdAuction() ارسال میشود. مقدار requestId از فراخوانی getInterestGroupAdAuctionData() در مرحله ۱ نیز به حراج ارسال میشود.
// 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 اجرا شده است را میپذیرد.
برای دیدن نمونهای از این فراخوانی، به کد جاوا اسکریپت فروشنده مربوط به برنامه آزمایشی محلی مراجعه کنید.
حراج ترکیبی
برای اجرای یک حراج 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 برای پیکربندی سطح بالا و پیکربندیهای کامپوننت یکسان است.
برای دیدن نمونهای از این فراخوانی، به کد جاوا اسکریپت فروشنده مربوط به برنامه آزمایشی محلی مراجعه کنید.
حراج چند فروشندهای
اگر شما یک فروشنده سطح بالا هستید که یک حراج چند فروشندهای هماهنگشده با دستگاه را اداره میکنید، هر فروشنده قطعات، نتیجه حراج 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',
}
]
})
برای دیدن نمونهای از این فراخوانی، به کد جاوا اسکریپت فروشنده مربوط به برنامه آزمایشی محلی مراجعه کنید.
مراحل بعدی
پس از مطالعه این راهنما، میتوانید مراحل زیر را انجام دهید:
بیشتر بدانید
- برای درک عمیقتر، به توضیحات زیر در GitHub مراجعه کنید:
- درباره معماری B&A برای وب بیشتر بدانید
- با دنبال کردن آزمایشگاه کد تست محلی سرتاسری، با مخاطب محافظتشده با B&A آزمایش کنید.
سوالی دارید؟
- اگر در مورد خدمات مناقصه و مزایده سوالی دارید، در مخزن خدمات B&A یک موضوع (issue) باز کنید .