Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Link from '@docusaurus/Link';

# POST /identity/buckets

ソルトバケットのローテーションをモニターします
<Link href="../ref-info/glossary-uid#gl-salt-bucket">salt buckets</Link> のローテーションをモニターします

Used by: このエンドポイントは、主に広告主とデータプロバイダーによって使用されます。詳細は [Advertiser/Data Provider Integration Guide](../guides/advertiser-dataprovider-guide.md) を参照してください。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Link from '@docusaurus/Link';

# POST /identity/map

複数のメールアドレス、電話番号、またはそれぞれのハッシュを、raw UID2 とソルトバケット ID にマッピングします。このエンドポイントを使用して、オプトアウト情報の更新をチェックすることもできます
複数のメールアドレス、電話番号、またはそれぞれのハッシュを、raw UID2 と <Link href="../ref-info/glossary-uid#gl-salt-bucket-id">salt bucket IDs</Link> にマッピングします。このエンドポイントを使用して、オプトアウト情報の更新をチェックすることもできます

Used by: このエンドポイントは、主に広告主やデータプロバイダーが使用します。詳細は [Advertiser/Data Provider Integration Guide](../guides/advertiser-dataprovider-guide.md) を参照してください。

Expand All @@ -19,7 +19,7 @@ Used by: このエンドポイントは、主に広告主やデータプロバ

- リクエストの最大サイズは 1MB です。
- 大量のメールアドレス、電話番号、またはそれぞれのハッシュをマップするには、1 バッチあたり最大 5,000 アイテムのバッチサイズで、それらを *連続した* バッチで送信してください。
- Private Operator を使用している場合を除き、バッチを並行して送信しないでください。つまり、1 つの HTTP 接続を使用して、[directly identifying information (DII)](../ref-info/glossary-uid.md#gl-dii) を連続してマッピングしてください。
- <Link href="../ref-info/glossary-uid#gl-private-operator">Private Operator</Link> を使用している場合を除き、バッチを並行して送信しないでください。つまり、単一の HTTP 接続を使用して、[directly identifying information (DII)](../ref-info/glossary-uid.md#gl-dii) を連続してマッピングしてください。
- メールアドレス、電話番号、またはそれぞれのハッシュのマッピングを必ず保存してください。<br/>マッピングを保存しないと、数百万のメールアドレスや電話番号をマッピングする必要がある場合に、処理時間が大幅に増加する可能性があります。しかし、実際に更新が必要なマッピングのみを再計算することで、毎日更新が必要な raw UID2 の数は約 1/365 となり、総処理時間を短縮できます。[Advertiser/Data Provider Integration Guide](../guides/advertiser-dataprovider-guide.md) と [FAQs for Advertisers and Data Providers](../getting-started/gs-faqs.md#faqs-for-advertisers-and-data-providers) も参照してください。

## Request Format
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Link from '@docusaurus/Link';

# POST /optout/status

raw UID2 のオプトアウトステータスを確認します。指定された raw UID2 のリストを使用して、このエンドポイントはオプトアウトした raw UID2 とそのオプトアウトが行われた時刻を返します。詳細は [User Opt-Out](../getting-started/gs-opt-out.md) を参照してください。
<Link href="../ref-info/glossary-uid#gl-raw-uid2">raw UID2s</Link> のオプトアウトステータスを確認します。指定された raw UID2 のリストを使用して、このエンドポイントはオプトアウトした raw UID2 とそのオプトアウトが行われた時刻を返します。詳細は [User Opt-Out](../getting-started/gs-opt-out.md) を参照してください。

Used by: このエンドポイントは、主に広告主、データプロバイダー、DSP、共有者によって使用されます。一般的には、元のメールアドレスや電話番号にアクセスできないが、オプトアウトステータスを知りたい参加者向けです。

Expand All @@ -24,7 +24,7 @@ Used by: このエンドポイントは、主に広告主、データプロバ
このエンドポイントへのリクエストのバッチを管理するための主要なガイドラインは次のとおりです:

- 多数の UID2 のオプトアウトステータスを確認するには、1 バッチあたりのバッチサイズが最大 5,000 件となるように、順次バッチを送信してください。
- Private Operator を使用している場合を除き、バッチを並行して送信しないでください。つまり、1 つの HTTP 接続を使用して、連続して raw UID2 のバッチを送信してください。
- <Link href="../ref-info/glossary-uid#gl-private-operator">Private Operator</Link> を使用している場合を除き、バッチを並行して送信しないでください。つまり、複数の並列接続を作成せず、単一の HTTP 接続を使用して、連続して raw UID2 のバッチを送信してください。

## Request Format

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Used by: このエンドポイントは、主にパブリッシャーが使用

このエンドポイントについて知っておくべきことは、以下のとおりです:

- トークン更新のリクエストには暗号化は必要ありません
- `POST /token/refresh` えんどぽいんとへのリクエストには暗号化は不要です
- リクエストが HTTP ステータスコード 200 で成功すると、新しい UID2 Token または Out-Out 情報が返されます。
- 成功したレスポンスは、そのレスポンスに新しいトークンまたは Opt-Out 情報が含まれているかどうかにかかわらず暗号化されます。エラーレスポンスは暗号化されません。
- レスポンスを復号化するには、このトークンに対する最新の `refresh_response_key` 値を使用します。`refresh_response_key` の値は、[POST&nbsp;/token/generate](post-token-generate.md) と `POST /token/refresh` のレスポンスで返されます。トークンがリフレッシュされるたびに、新しい `refresh_response_key` が返されます。現在のレスポンスを復号化するには、必ず最新のものを使用してください。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Link from '@docusaurus/Link';

# UID2 Credentials

UID2 <a href="/docs/intro#participants">参加者</a>はそれぞれ、固有の認証情報のセットを取得します。取得する認証情報のセットは、次の表に示すように、UID2 にどのように参加しているかによって決まります。
UID2 <a href="../intro#participants">参加者</a>はそれぞれ、固有の認証情報のセットを取得します。取得する認証情報のセットは、次の表に示すように、UID2 にどのように参加しているかによって決まります。

| Audience | Credentials | Integration |
| :--- | :--- | :--- |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ Maven を使用している場合は、以下の最小限の `pom.xml` を使用

このファイルには.NET 7.0が必要です。必要であれば、それ以前のバージョンを使用することもできますが、.NET Core 3.0以降でなければなりません。バージョンを変更するには、[top-level statements](https://learn.microsoft.com/ja-jp/dotnet/csharp/fundamentals/program-structure/top-level-statements) を Main メソッドに、[using 宣言](https://learn.microsoft.com/ja-jp/cpp/cpp/using-declaration?view=msvc-170) を [using ステートメント](https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/proposals/csharp-8.0/using) に置き換えてください。

</TabItem>
<TabItem value='go' label='Go'>

以下のコード例では、Go を使用してリクエストを暗号化し、レスポンスを復号化します。必要なパラメータはファイルの一番下に記載されています。または、`go run uid2_request.go` を実行して確認できます。

</TabItem>
</Tabs>

Expand Down Expand Up @@ -574,5 +579,246 @@ else
Console.WriteLine(JsonSerializer.Serialize(jDoc, new JsonSerializerOptions { WriteIndented = true }));
}
```

</TabItem>
</Tabs>
<TabItem value='go' label='Go'>

```go title="uid2_request.go"
package main

import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
"time"
)

const (
nonceLengthBytes = 8
gcmIVLengthBytes = 12
)

func main() {
subArgs := os.Args[1:]

if len(subArgs) != 3 && len(subArgs) != 4 {
printUsage()
os.Exit(1)
}

url := subArgs[0]

response, err := func() (map[string]interface{}, error) {
if subArgs[1] == "--refresh-token" {
return refresh(url, subArgs[2], subArgs[3])
} else {
return generate(url, subArgs[1], subArgs[2])
}
}()

if err != nil {
log.Fatal(err)
}

prettyPrint(response)
}

func refresh(url string, refreshToken string, refreshResponseKey string) (map[string]interface{}, error) {
fmt.Printf("Request: Sending refresh_token to %s\n", url)

response, err := http.Post(url, "", strings.NewReader(refreshToken))
if err != nil {
return nil, err
}

return deserializeResponse(response, refreshResponseKey, true)
}

func generate(url string, apiKey string, secret string) (map[string]interface{}, error) {
payload, err := io.ReadAll(os.Stdin)
if err != nil {
return nil, err
}

key, err := base64.StdEncoding.DecodeString(secret)
if err != nil {
return nil, err
}

unencryptedEnvelope, err := makeUnencryptedEnvelope(payload)
if err != nil {
return nil, err
}

envelope, err := makeEncryptedEnvelope(unencryptedEnvelope, key)
if err != nil {
return nil, err
}

req, err := http.NewRequest("POST", url, strings.NewReader(base64.StdEncoding.EncodeToString(envelope)))
if err != nil {
return nil, err
}

req.Header.Add("Authorization", "Bearer "+apiKey)

response, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}

return deserializeResponse(response, secret, false)
}

func aesgcm(key []byte) (cipher.AEAD, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}

return cipher.NewGCM(block)
}

func decryptResponse(ciphertext string, key string) ([]byte, error) {
ciphertextBytes, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return nil, err
}

keyBytes, err := base64.StdEncoding.DecodeString(key)
if err != nil {
return nil, err
}

aesgcm, err := aesgcm(keyBytes)
if err != nil {
return nil, err
}

iv := ciphertextBytes[:gcmIVLengthBytes]
return aesgcm.Open(nil, iv, ciphertextBytes[gcmIVLengthBytes:], nil)
}

func deserialize(bytes []byte) (map[string]interface{}, error) {
var anyJson map[string]interface{}
err := json.Unmarshal(bytes, &anyJson)
return anyJson, err
}

func prettyPrint(obj map[string]interface{}) error {
bytes, err := json.MarshalIndent(obj, "", " ")
if err != nil {
return err
}

fmt.Println(string(bytes))
return nil
}

func checkStatusCode(response *http.Response, body []byte) error {
if response.StatusCode != http.StatusOK {
return fmt.Errorf("Response: Error HTTP status code %d\n%s", response.StatusCode, body)
}

return nil
}

func makeUnencryptedEnvelope(payload []byte) ([]byte, error) {
timestamp := make([]byte, 8)
binary.BigEndian.PutUint64(timestamp, uint64(time.Now().UnixMilli()))

nonce := make([]byte, nonceLengthBytes)
_, err := rand.Read(nonce)
if err != nil {
return nil, err
}

var body bytes.Buffer
body.Write(timestamp)
body.Write(nonce)
body.Write(payload)
return body.Bytes(), nil
}

func encrypt(plaintext []byte, iv []byte, key []byte) ([]byte, error) {
aesgcm, err := aesgcm(key)
if err != nil {
return nil, err
}

return aesgcm.Seal(nil, iv, plaintext, nil), nil
}

func makeEncryptedEnvelope(payload []byte, key []byte) ([]byte, error) {
iv := make([]byte, gcmIVLengthBytes)
_, err := rand.Read(iv)
if err != nil {
return nil, err
}

ciphertext, err := encrypt(payload, iv, key)
if err != nil {
return nil, err
}

var envelope bytes.Buffer
envelope.WriteByte(1)
envelope.Write(iv)
envelope.Write(ciphertext)
return envelope.Bytes(), nil
}

func deserializeResponse(response *http.Response, key string, isRefresh bool) (map[string]interface{}, error) {
defer response.Body.Close()

body, err := io.ReadAll(response.Body)
if err != nil {
return nil, err
}

err = checkStatusCode(response, body)
if err != nil {
return nil, err
}

plaintext, err := decryptResponse(string(body), key)
if err != nil {
return nil, err
}

offset := 16
if isRefresh {
offset = 0
}

return deserialize(plaintext[offset:])
}

func printUsage() {
fmt.Println(`Usage:
echo '<json>' | go run uid2_request.go <url> <api_key> <client_secret>

Example:
echo '{"email": "[email protected]", "optout_check": 1}' | go run uid2_request.go https://prod.uidapi.com/v2/token/generate UID2-C-L-999-fCXrMM.fsR3mDqAXELtWWMS+xG1s7RdgRTMqdOH2qaAo= wJ0hP19QU4hmpB64Y3fV2dAed8t/mupw3sjN5jNRFzg=


Refresh Token Usage:
go run uid2_request.go <url> --refresh-token <refresh_token> <refresh_response_key>

Refresh Token Usage example:
go run uid2_request.go https://prod.uidapi.com/v2/token/refresh --refresh-token AAAAAxxJ...(truncated, total 388 chars) v2ixfQv8eaYNBpDsk5ktJ1yT4445eT47iKC66YJfb1s=`)
}
```
</TabItem>

</Tabs>
Loading
Loading