ストリーム セッション リクエストを認証する

ストリーム リクエストは、ライブ配信イベントのセッションを登録します。詳しくは、ストリーム リクエストを行うをご覧ください。

このページでは、HMAC トークンを使用してストリーム リクエストを認証する方法について説明します。

始める前に

続行する前に、次の操作を行います。

  • 前提条件を満たしている。
  • Google Ad Manager アカウントで、ライブ ストリーム イベントに対して**ストリーム作成認証キー**を有効にします。トークン認証を使用する場合は、キーが必要です。

HMAC トークンを生成する

トークンを生成する手順は次のとおりです。

  1. ライブ ストリームのアセットキーと有効期限を収集します。詳しくは、 DAI ストリーム セッションを作成するリクエストの認証を有効にするをご覧ください。
  2. 次のパラメータをアルファベット順に並べ替え、チルダ ~ 文字で区切ります。

    event=ASSET_KEY~exp=EXPIRATION
    

    次のように置き換えます。

    • ASSET_KEY: 必須 。ライブ ストリーム イベントのアセットキー。
    • EXPIRATION: 必須 。トークンの有効期限のタイムスタンプ(Unix エポック時間)。
  3. DAI 認証キー を使用して、トークン文字列の SHA-256 ハッシュを計算します。

  4. ハッシュ出力を 16 進数でフォーマットします。

  5. トークン文字列に署名するには、先ほど収集したパラメータの末尾に署名を追加します。

    event=...~hmac=HMAC_SIGNATURE
    

    HMAC_SIGNATURE は、DAI 認証キーを使用してトークン文字列をハッシュして生成した署名に置き換えます。

  6. 署名付きトークン文字列を安全に渡すには、署名付きトークン文字列に URL エンコードを適用します。

次の例では、60 秒以内に期限切れになるトークン文字列に署名してエンコードします。

# Add 60 seconds to the current time
future_epoch=$((EPOCHSECONDS + 60))

echo "Current: $EPOCHSECONDS"
echo "Future: $future_epoch"
# Current: 1767389133
# Future: 1767389193

# Sample DAI stream authentication key
key="DE0E9..."

# Sort parameters in the token string
token="event=YRB0Bl0oQRCb5J-maPpJUQ~exp=1767389193"

# Generate the token's signature.
echo -n $token | openssl dgst -sha256 -mac HMAC -macopt key:$key
# SHA2-256(stdin)= 9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248

# Sign the token: event=YRB0Bl0oQRCb5J-maPpJUQ~exp=1767389193~hmac=9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248

# Encode the token: event%3DYRB0Bl0oQRCb5J%2DmaPpJUQ%7Eexp%3D1767389193%7Ehmac%3D9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248

HMAC トークンを使用してライブ ストリーム セッションをリクエストする

HMAC トークンを使用してストリーム作成リクエストを認証するには、次のいずれかを行います。

Authorization リクエスト ヘッダー

  curl "https://dai.google.com/linear/v1/hls/event/YRB0Bl0oQRCb5J-maPpJUQ/stream" \
  -X POST \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Authorization: DCLKDAI token=event%3DYRB0Bl0oQRCb5J%2DmaPpJUQ%7Eexp%3D1767389193%7Ehmac%3D9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248"

クエリ文字列パラメータ

  curl "https://dai.google.com/linear/v1/hls/event/YRB0Bl0oQRCb5J-maPpJUQ/stream?auth-token=event%3DYRB0Bl0oQRCb5J%2DmaPpJUQ%7Eexp%3D1767389193%7Ehmac%3D9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248" \
  -X POST \
  -H "Content-Type: application/x-www-form-urlencoded"

フォームデータ フィールド

  curl "https://dai.google.com/linear/v1/hls/event/YRB0Bl0oQRCb5J-maPpJUQ/stream" \
  -X POST \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "auth-token=event%3DYRB0Bl0oQRCb5J%2DmaPpJUQ%7Eexp%3D1767389193%7Ehmac%3D9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248"

成功すると、次のような JSON レスポンスが表示されます。

  {
  "hls_master_playlist": "https://dai.google.com/linear/hls/pa/event/YRB0Bl0oQRCb5J-maPpJUQ/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/master.m3u8",
  "media_verification_url": "https://dai.google.com/view/p/service/linear/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/loc/DLS/network/21775744923/event/YRB0Bl0oQRCb5J-maPpJUQ/media/",
  "metadata_url": "https://dai.google.com/linear/v1/pa/event/YRB0Bl0oQRCb5J-maPpJUQ/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/metadata",
  "polling_frequency": 10,
  "session_update_url": "https://dai.google.com/linear/v1/pa/event/YRB0Bl0oQRCb5J-maPpJUQ/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/session",
  "stream_id": "e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS",
  "stream_manifest": "https://dai.google.com/linear/hls/pa/event/YRB0Bl0oQRCb5J-maPpJUQ/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/master.m3u8"
  }

レスポンスの構造とステータス コードについては、Method: stream をご覧ください。 認証に失敗すると、次のエラーが表示されます。

  <!DOCTYPE html>
  <html lang=en>
    <meta charset=utf-8>
    <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
    <title>Error 401 (Unauthorized)!!1</title>
    ...
    <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
    <p><b>401.</b> <ins>That’s an error.</ins>
    <p><ins>That’s all we know.</ins>