Découvrez comment la Realtime API authentifie les connexions à l'aide de jetons. Cette rubrique explique également comment obtenir une clé API et s'authentifier via les protocoles WebSocket, WebRTC et AOQ.
La Realtime API utilise des clés API pour l'authentification. Que vous vous connectiez via AOQ, WebRTC ou WebSocket, vous devez transmettre un jeton porteur (bearer token) dans l'en-tête de requête HTTP Authorization.
L'authentification s'effectue uniquement lors de l'établissement de la connexion. Une fois la connexion établie, la transmission des données ne nécessite pas de nouvelle authentification.
Le tableau suivant compare les méthodes d'authentification des trois protocoles :
Protocole | Moment de l'authentification | Méthode d'authentification | Notes |
|---|---|---|---|
AOQ | Lorsque l'AppServer métier sollicite la passerelle | En-tête HTTP | La clé API est utilisée exclusivement côté serveur. Le client emploie le jeton renvoyé par la passerelle |
WebRTC | Pendant la requête HTTP d'échange SDP | En-tête HTTP | Le client ou le serveur initie l'échange SDP avec la clé API |
WebSocket | Lors du handshake WebSocket | En-tête HTTP | Le client ou le serveur se connecte directement avec la clé API |
Obtenir une clé API
Étape 1 : Activer Model Studio
- Accédez à la console Alibaba Cloud Model Studio et connectez-vous avec votre compte Alibaba Cloud.
- S'il s'agit de votre première utilisation du service, suivez les instructions à l'écran pour l'activer.
Étape 2 : Créer une clé API
- Dans le volet de navigation de gauche de la console, sélectionnez API Key.
- Cliquez sur Create API Key et choisissez l'espace de travail à associer à cette clé.
- Une fois la clé créée, copiez-la et stockez-la immédiatement.
ImportantNote de sécurité : La clé API constitue votre unique identifiant pour accéder au service. Ne l'intégrez jamais en dur dans le code client et ne la validez pas dans un dépôt de code. Gérez-la via des variables d'environnement ou distribuez-la depuis un service backend.
Détails de l'authentification de connexion
Authentification via le protocole AOQ
AOQ repose sur un modèle d'authentification par proxy côté serveur : la clé API est utilisée uniquement sur l'AppServer métier. Le client se connecte à l'aide d'un jeton temporaire renvoyé par la passerelle, ce qui évite d'exposer la clé API côté client.
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}\"}"
Champs de la requête
Élément | Valeur | Description |
|---|---|---|
endpoint | Sélectionnez un domaine d'accès selon votre scénario métier | Définit le domaine d'accès. Pour plus de détails, consultez Régions et domaines d'accès |
Content-Type |
| Spécifie le type de message |
Authorization |
| Votre clé API |
x-dashscope-rtc-transport |
| Indique le protocole AOQ |
clientIp | L'adresse IP publique réelle du client | Facultatif. En l'absence de cette valeur, l'adresse IP qui sollicite la passerelle Model Studio est utilisée. Si elle est renseignée, la valeur clientIp est prioritaire. La Realtime API attribue alors le point d'accès Relay optimal en fonction de l'adresse IP du client |
Exemple de réponse
{
"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"}
}
Champs de la réponse
Champ | Description |
|---|---|
sid | ID de session unique |
aoqTokenForClient | Jeton de connexion client. Transmettez-le au champ token du SDK |
clientRelayEndpoints | Tableau des points d'accès Relay (endpoint + port) |
clientRelayCertFingerprint | Empreinte du certificat TLS Relay |
sidExpiresInSecs | Durée d'expiration de la session, en secondes |
extraInfo.workspaceIdHash | Hachage de l'ID de l'espace de travail |
Exemple de connexion avec le SDK client AOQ
RemarqueLe champ clientIp est facultatif dans le corps de la requête. S'il n'est pas spécifié, l'adresse IP qui sollicite la passerelle Model Studio fait office d'IP client. Lorsqu'il est renseigné, la valeur clientIp est prioritaire. Configurez votre AppServer métier pour qu'il récupère l'adresse IP réelle du client et la transmette, afin d'obtenir le point d'accès Relay optimal.
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()
// Fall back to the array index when route_index is missing
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();
// Fall back to the array index when route_index is missing
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'] ?? ''),
// Fall back to the array index when route_index is missing
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);
Authentification via le protocole WebRTC
WebRTC effectue l'échange SDP via une requête HTTP POST ; c'est à cette étape que l'authentification a lieu. Le client envoie le SDP Offer au serveur, qui renvoie en retour le SDP Answer.
Élément | Valeur | Description |
|---|---|---|
Méthode de requête | POST | - |
URL de requête |
| Remplacez endpoint et model_name. L'URL de connexion varie selon le modèle. Pour plus de détails, consultez Connexion WebRTC |
Content-Type |
| Le corps de la requête contient une chaîne SDP |
Authorization |
| Votre clé API |
Réponse | HTTP 200 avec le SDP Answer | Renvoie un code d'état 4xx en cas d'échec |
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);
// Send after ICE gathering is complete
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 });
Authentification via le protocole WebSocket
L'authentification WebSocket est la plus simple : il suffit de transmettre la clé API dans un en-tête HTTP lors de l'établissement de la connexion.
Élément | Valeur | Description |
|---|---|---|
URL de connexion |
| L'URL de connexion varie selon le modèle. Pour plus de détails, consultez Connexion WebSocket |
Authorization |
| Votre clé 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()