Pelajari cara Realtime API mengotentikasi koneksi menggunakan token, termasuk cara memperoleh Kunci API dan melakukan otentikasi melalui protokol WebSocket, WebRTC, dan AOQ.
Realtime API menggunakan Kunci API untuk otentikasi. Baik Anda terhubung melalui AOQ, WebRTC, maupun WebSocket, Anda harus menyertakan bearer token dalam header permintaan HTTP Authorization.
Otentikasi hanya dilakukan selama penyiapan koneksi. Setelah koneksi terbentuk, transmisi data tidak memerlukan otentikasi ulang.
Tabel berikut membandingkan cara ketiga protokol tersebut melakukan otentikasi:
Protokol | Kapan otentikasi dilakukan | Metode otentikasi | Catatan |
|---|---|---|---|
AOQ | Saat AppServer bisnis mengirim permintaan ke gerbang | Header HTTP | Kunci API hanya digunakan di sisi server. Klien menggunakan token yang dikembalikan oleh gerbang |
WebRTC | Selama permintaan HTTP pertukaran SDP | Header HTTP | Klien atau server memulai pertukaran SDP dengan Kunci API |
WebSocket | Selama handshake WebSocket | Header HTTP | Klien atau server terhubung langsung dengan Kunci API |
Dapatkan Kunci API
Langkah 1: Aktifkan Model Studio
- Buka Konsol Alibaba Cloud Model Studio dan masuk dengan Akun Alibaba Cloud Anda.
- Jika ini pertama kalinya Anda menggunakan layanan ini, ikuti petunjuk di layar untuk mengaktifkannya.
Langkah 2: Buat Kunci API
- Di panel navigasi kiri Konsol, pilih API Key.
- Klik Create API Key dan pilih ruang kerja yang akan dikaitkan dengan kunci tersebut.
- Setelah kunci dibuat, segera salin dan simpan.
PentingCatatan keamanan: Kunci API adalah satu-satunya kredensial Anda untuk mengakses layanan ini. Jangan hard-code di kode klien atau commit ke repositori kode. Kelola melalui variabel lingkungan atau distribusikan dari layanan backend.
Detail otentikasi koneksi
Otentikasi protokol AOQ
AOQ menggunakan model otentikasi proxy sisi server: Kunci API hanya digunakan di AppServer bisnis. Klien terhubung dengan token sementara yang dikembalikan oleh gerbang, sehingga Kunci API tidak disimpan di sisi klien.
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}\"}"
Bidang permintaan
Item | Nilai | Deskripsi |
|---|---|---|
endpoint | Pilih domain akses berdasarkan skenario bisnis Anda | Menentukan domain akses. Untuk detailnya, lihat Wilayah dan Domain Akses |
Content-Type |
| Menentukan jenis pesan |
Authorization |
| Kunci API Anda |
x-dashscope-rtc-transport |
| Menentukan protokol AOQ |
clientIp | Alamat IP publik asli klien | Opsional. Jika tidak ditentukan, alamat IP yang mengirim permintaan ke gerbang Model Studio akan digunakan. Jika ditentukan, nilai clientIp memiliki prioritas lebih tinggi. Realtime API menetapkan titik akses Relay terbaik berdasarkan alamat IP klien |
Contoh tanggapan
{
"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"}
}
Bidang tanggapan
Bidang | Deskripsi |
|---|---|
sid | ID sesi unik |
aoqTokenForClient | Token koneksi klien. Masukkan ke bidang token SDK |
clientRelayEndpoints | Array titik akses Relay (endpoint + port) |
clientRelayCertFingerprint | Sidik jari sertifikat TLS Relay |
sidExpiresInSecs | Waktu kedaluwarsa sesi, dalam detik |
extraInfo.workspaceIdHash | Hash ID ruang kerja |
Contoh koneksi AOQ Client SDK
CatatanclientIp adalah bidang opsional dalam badan permintaan. Jika tidak ditentukan, alamat IP yang mengirim permintaan ke gerbang Model Studio akan digunakan sebagai alamat IP klien. Jika ditentukan, nilai clientIp memiliki prioritas lebih tinggi. Pastikan AppServer bisnis Anda mendapatkan alamat IP asli klien dan meneruskannya agar mendapatkan titik akses Relay terbaik.
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()
// Gunakan indeks array jika route_index tidak tersedia
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();
// Gunakan indeks array jika route_index tidak tersedia
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'] ?? ''),
// Gunakan indeks array jika route_index tidak tersedia
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);
Otentikasi protokol WebRTC
WebRTC menyelesaikan pertukaran SDP melalui permintaan HTTP POST, dan otentikasi dilakukan pada tahap ini. Klien mengirim Offer SDP ke server, dan server mengembalikan Answer SDP.
Item | Nilai | Deskripsi |
|---|---|---|
Metode permintaan | POST | - |
URL permintaan |
| Ganti endpoint dan model_name. URL koneksi bervariasi tergantung model. Untuk detailnya, lihat Koneksi WebRTC |
Content-Type |
| Badan permintaan berupa string SDP |
Authorization |
| Kunci API Anda |
Tanggapan | HTTP 200 dengan Answer SDP | Mengembalikan kode status 4xx jika gagal |
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);
// Kirim setelah pengumpulan ICE selesai
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 });
Otentikasi protokol WebSocket
WebSocket memiliki mekanisme otentikasi paling sederhana: kirim Kunci API dalam header HTTP saat membuat koneksi.
Item | Nilai | Deskripsi |
|---|---|---|
URL koneksi |
| URL koneksi bervariasi tergantung model. Untuk detailnya, lihat Koneksi WebSocket |
Authorization |
| Kunci API Anda |
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()