すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Model Studio:トークン認証

最終更新日:Sep 02, 2026

リアルタイム API でトークンを使用して接続を認証する方法、API キーの取得方法、および WebSocket、WebRTC、AOQ プロトコルでの認証方法について説明します。

リアルタイム API は認証に API キーを使用します。AOQ、WebRTC、または WebSocket のいずれを介して接続する場合でも、Authorization HTTP リクエストヘッダーでベアラートークンを渡します。

認証は接続の確立時にのみ行われます。接続が確立された後のデータ送信では、再認証は不要です。

次の表は、3 つのプロトコルの認証方法を比較したものです。

プロトコル

認証が行われるタイミング

認証方法

備考

AOQ

ビジネス AppServer がゲートウェイにリクエストする際

HTTP ヘッダー Authorization: Bearer <API_KEY>

API キーはサーバーサイドでのみ使用されます。クライアントはゲートウェイから返されたトークンを使用します。

WebRTC

SDP 交換の HTTP リクエスト時

HTTP ヘッダー Authorization: Bearer <API_KEY>

クライアントまたはサーバーが API キーを使用して SDP 交換を開始します。

WebSocket

WebSocket ハンドシェイク中

HTTP ヘッダー Authorization: Bearer <API_KEY>

クライアントまたはサーバーが API キーを使用して直接接続します。

API キーの取得

ステップ 1:Model Studio の有効化

  1. Alibaba Cloud Model Studio コンソールに移動し、Alibaba Cloud アカウントでログインします。
  2. 初めてサービスをご利用になる場合は、画面の指示に従ってサービスを有効化してください。

ステップ 2:API キーの作成

  1. コンソールのナビゲーションペインで、[API Key] を選択します。
  2. [Create API Key] をクリックし、キーに関連付けるワークスペースを選択します。
  3. キーが作成されたら、すぐにコピーして安全な場所に保管してください

重要セキュリティに関する注意:API キーは、サービスにアクセスするための唯一の認証情報です。クライアントコードにハードコーディングしたり、コードリポジトリにコミットしたりしないでください。環境変数で管理するか、バックエンドサービスから配布するようにしてください。

接続認証の詳細

AOQ プロトコル認証

AOQ はサーバーサイドプロキシ認証モデルを使用します。API キーはビジネス AppServer でのみ使用されます。クライアントはゲートウェイから返された一時的なトークンで接続するため、API キーがクライアント側に渡ることはありません。

Token authentication
curl -X POST \
  "https://{endpoint}/api/v1/webrtc/realtime?model=qwen3.5-omni-plus-realtime" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${DASHSCOPE_API_KEY}" \
  -H "x-dashscope-rtc-transport: moq" \
  -d "{\"clientIp\": \"${CLIENT_REAL_IP}\"}"
curl -X POST \
  "https://{endpoint}/api/v1/webrtc/inference?model=fun-asr-realtime" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${DASHSCOPE_API_KEY}" \
  -H "x-dashscope-rtc-transport: moq" \
  -d "{\"clientIp\": \"${CLIENT_REAL_IP}\"}"

リクエストフィールド

項目

説明

endpoint

ビジネスシナリオに応じて選択するアクセスドメイン

アクセスドメインを指定します。詳細については、「リージョンとアクセスドメイン」をご参照ください。

Content-Type

application/json

メッセージタイプを指定します

Authorization

Bearer <YOUR_API_KEY>

ご自身の API キー

x-dashscope-rtc-transport

moq

AOQ プロトコルを指定します

clientIp

クライアントの実際のパブリック IP アドレス

オプション。指定しない場合、Model Studio ゲートウェイへのリクエスト元の IP アドレスが使用されます。指定した場合、clientIp の値が優先されます。リアルタイム API は、クライアントの IP アドレスに基づいて最適な Relay アクセスポイントを割り当てます。

レスポンスの例

{
    "sid": "1d06b55683db49bba67a407902f62d02:1782706970:69aecdc5...",
    "aoqTokenForClient": "ecc1a46015d5496ca4ff7a48281eb739",
    "clientRelayEndpoints": [{"endpoint": "121.199.XX.XX", "port": 8443, "route_index": 0}],
    "clientRelayCertFingerprint": "sha256/99843495...",
    "sidExpiresInSecs": 7200,
    "extraInfo": {"workspaceIdHash": "2021b6f98cea4cff"}
}

レスポンスフィールド

フィールド

説明

sid

一意のセッション ID

aoqTokenForClient

クライアント接続トークン。SDK の token フィールドに渡します。

clientRelayEndpoints

Relay アクセスポイント (endpoint + port) の配列

clientRelayCertFingerprint

Relay TLS 証明書のフィンガープリント

sidExpiresInSecs

セッションの有効期限 (秒)

extraInfo.workspaceIdHash

ワークスペース ID のハッシュ

AOQ クライアント SDK 接続の例

注記clientIp は、リクエストボディ内の省略可能なフィールドです。指定されていない場合、Model Studio ゲートウェイにリクエストする IP アドレスがクライアント IP として使用されます。指定された場合、clientIp の値が優先されます。最適なリレーアクセスポイントを取得するには、お使いのビジネス AppServer でクライアントの実際の IP アドレスを取得し、渡してください。

let resp = try JSONDecoder().decode(AllocateResponse.self, from: responseData)

let config = AoqConnectConfig()
config.token = resp.aoqTokenForClient
config.sid = resp.sid
config.certFingerprint = resp.clientRelayCertFingerprint
config.relayEndpoints = resp.clientRelayEndpoints.enumerated().map { index, item in
    let ep = AoqRelayEndpoint()
    // route_index がない場合は、配列のインデックスにフォールバックします
    ep.routeIndex = item.routeIndex ?? index
    ep.endpoint = item.endpoint
    ep.port = item.port
    return ep
}
config.workspaceIdHash = resp.extraInfo?.workspaceIdHash ?? ""

let audioTrack = AoqTrackParam()
audioTrack.trackType = .audio
let dataTrack = AoqTrackParam()
dataTrack.trackType = .data
config.publishTracks = [audioTrack, dataTrack]
config.subscribeTracks = [audioTrack, dataTrack]

engine.connect(config)
JSONObject obj = new JSONObject(responseText);
AoqClientEngine.AoqConnectConfig cfg = new AoqClientEngine.AoqConnectConfig();
cfg.token = obj.optString("aoqTokenForClient", "");
cfg.sid = obj.optString("sid", "");
cfg.certFingerprint = obj.optString("clientRelayCertFingerprint", "");

JSONArray arr = obj.optJSONArray("clientRelayEndpoints");
if (arr != null) {
    for (int i = 0; i < arr.length(); i++) {
        JSONObject o = arr.optJSONObject(i);
        AoqClientEngine.AoqRelayEndpoint ep = new AoqClientEngine.AoqRelayEndpoint();
        // route_index がない場合は、配列のインデックスにフォールバックします
        ep.routeIndex = o.has("route_index") ? o.optInt("route_index", i) : i;
        ep.endpoint = o.optString("endpoint", "");
        ep.port = o.optInt("port", 0);
        cfg.relayEndpoints.add(ep);
    }
}

JSONObject ext = obj.optJSONObject("extraInfo");
cfg.workspaceIdHash = ext != null ? ext.optString("workspaceIdHash", "") : "";

AoqClientEngine.AoqTrackParam audio = new AoqClientEngine.AoqTrackParam();
audio.trackType = AoqClientEngine.AoqTrackType.AoqTrackTypeAudio;
AoqClientEngine.AoqTrackParam data = new AoqClientEngine.AoqTrackParam();
data.trackType = AoqClientEngine.AoqTrackType.AoqTrackTypeData;
cfg.publishTracks.add(audio);
cfg.publishTracks.add(data);
cfg.subscribeTracks.add(audio);
cfg.subscribeTracks.add(data);

engine.connect(cfg);
const obj = JSON.parse(responseText) as Record<string, Object | undefined>;
const cfg: AoqConnectConfig = {
    token: String(obj['aoqTokenForClient'] ?? ''),
    sid: String(obj['sid'] ?? ''),
    certFingerprint: String(obj['clientRelayCertFingerprint'] ?? ''),
    // route_index がない場合は、配列のインデックスにフォールバックします
    relayEndpoints: (obj['clientRelayEndpoints'] as Array<any>).map((item, index) => ({
        routeIndex: Number(item['route_index'] ?? index),
        endpoint: String(item['endpoint'] ?? ''),
        port: Number(item['port'] ?? 0)
    })),
    workspaceIdHash: String((obj['extraInfo'] as any)?.['workspaceIdHash'] ?? ''),
    publishTracks: [
        { trackType: AoqTrackType.AoqTrackTypeAudio },
        { trackType: AoqTrackType.AoqTrackTypeData }
    ],
    subscribeTracks: [
        { trackType: AoqTrackType.AoqTrackTypeAudio },
        { trackType: AoqTrackType.AoqTrackTypeData }
    ]
};
engine.connect(cfg);

WebRTC プロトコル認証

WebRTC は、HTTP POST リクエストを介して SDP 交換を完了し、認証はこの段階で行われます。クライアントは Offer SDP をサーバーに送信し、サーバーは Answer SDP を返します。

項目

説明

リクエストメソッド

POST

-

リクエスト URL

https://{endpoint}/api/v1/webrtc/realtime?model={model_name}

endpointmodel_name を置き換えてください。接続 URL はモデルによって異なります。詳細については、「WebRTC 接続」をご参照ください。

Content-Type

application/sdp

リクエストボディは SDP 文字列です。

Authorization

Bearer <API_KEY>

ご自身の API キー

レスポンス

Answer SDP を含む HTTP 200

失敗した場合は 4xx ステータスコードを返します。

const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
stream.getAudioTracks().forEach(t => pc.addTrack(t, stream));
pc.createDataChannel('oai-events');

const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

// ICE GATHERING が完了した後に送信します
const resp = await fetch(API_URL, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/sdp',
    'Authorization': `Bearer ${API_KEY}`,
  },
  body: pc.localDescription.sdp,
});
const answerSdp = await resp.text();
await pc.setRemoteDescription({ type: 'answer', sdp: answerSdp });

WebSocket プロトコル認証

WebSocket の認証は最もシンプルです。接続を確立する際に、HTTP ヘッダーで API キーを送信します。

項目

説明

接続 URL

wss://dashscope.aliyuncs.com/api-ws/v1/realtime?model={model_name}

接続 URL はモデルによって異なります。詳細については、「WebSocket 接続」をご参照ください。

Authorization

Bearer <API_KEY>

ご自身の API キー

import websocket, os
API_KEY = os.getenv("DASHSCOPE_API_KEY")
URL = "wss://dashscope.aliyuncs.com/api-ws/v1/realtime?model=qwen3.5-omni-plus-realtime"
ws = websocket.WebSocketApp(URL, header=["Authorization: Bearer " + API_KEY])
ws.run_forever()