Autenticação de token
Aprenda como a API Realtime autentica conexões com tokens, incluindo como obter uma chave de API e como autenticar através dos protocolos WebSocket, WebRTC e AOQ
A API Realtime usa chaves de API para autenticação. Quer você se conecte por AOQ, WebRTC ou WebSocket, você passa um token de portador no Authorization Cabeçalho de solicitação HTTP.
A autenticação acontece apenas durante a configuração da conexão. Após a conexão ser estabelecida, a transmissão de dados não requer nova autenticação.
A tabela a seguir compara como os três protocolos são autenticados:
| Protocolo | Quando a autenticação acontece | Método de autenticação | Notas |
|---|---|---|---|
| AOQ | Quando o AppServer empresarial solicita o gateway | Cabeçalho HTTP Authorization: Bearer $DASHSCOPE_API_KEY |
A chave API é usada apenas no lado do servidor. O cliente usa o token retornado pelo gateway |
| WebRTC | Durante a solicitação HTTP de troca SDP | Cabeçalho HTTP Authorization: Bearer $DASHSCOPE_API_KEY |
O cliente ou servidor inicia a troca SDP com a chave API |
| WebSocket | Durante o handshake do WebSocket | Cabeçalho HTTP Authorization: Bearer $DASHSCOPE_API_KEY |
O cliente ou servidor se conecta diretamente com a chave API |
Obtenha uma chave de API
Etapa 1: ativar QwenCloud
-
Vá para QwenCloud console e faça login com sua conta.
-
Se esta for a primeira vez que utiliza o serviço, siga as instruções na tela para ativá-lo.
Etapa 2: Crie uma chave de API
-
No painel de navegação esquerdo do console, escolha API Key.
-
Clique em Criar chave de API e selecione o espaço de trabalho para associar à chave.
-
Depois que a chave for criada, copie-a e armazene-a imediatamente.
Nota de segurança: A chave API é sua única credencial para acessar o serviço. Não codifique-o no código do cliente nem envie-o para um repositório de código. Gerencie-o por meio de variáveis de ambiente ou distribua-o por meio de um serviço de back-end.
Detalhes de autenticação de conexão
Autenticação do protocolo AOQ
AOQ usa um modelo de autenticação de proxy do lado do servidor: a chave de API é usada apenas no AppServer de negócios. O cliente se conecta a um token temporário retornado pelo gateway, que mantém a chave de API fora do cliente.

O exemplo em tempo real a seguir usa qwen3.8-omni-flash-realtime. Definir {endpoint} para maas.qwencloudapi.com.
Realtime protocol
```curl
curl -X POST \
"https://{endpoint}/api/v1/webrtc/realtime?model=qwen3.8-omni-flash-realtime" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "x-dashscope-rtc-transport: moq" \
-d "{\"clientIp\": \"${CLIENT_REAL_IP}\"}"
```
Inference protocol
```curl
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}\"}"
```
Campos de solicitação
| Item | Valor | Descrição |
|---|---|---|
| ponto final | Selecione um domínio de acesso com base no cenário do seu negócio | Especifica o domínio de acesso. Se você usar Plano de Token, o WorkspaceId no domínio de acesso é fixado em token-plan. |
| Tipo de conteúdo | application/json |
Especifica o tipo de mensagem |
| Autorização | Bearer $DASHSCOPE_API_KEY |
Sua chave API |
| x-dashscope-rtc-transport | moq |
Especifica o protocolo AOQ |
| clienteIp | O endereço IP público real do cliente | Opcional. Se não for especificado, o endereço IP que solicita o QwenCloud gateway é usado. Se especificado, o valor clientIp terá precedência. A API Realtime atribui o melhor ponto de acesso Relay com base no endereço IP do cliente |
Exemplo de resposta
{
"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"}
}
Campos de resposta
| Campo | Descrição |
|---|---|
| sid | ID de sessão exclusivo |
| aoqTokenForClient | Token de conexão do cliente. Passe para o campo token do SDK |
| clienteRelayEndpoints | Matriz de pontos de acesso Relay (endpoint + porta) |
| clientRelayCertFingerprint | Retransmitir impressão digital do certificado TLS |
| sidExpiresInSecs | Tempo de expiração da sessão, em segundos |
| extraInfo.workspaceIdHash | Hash de ID do espaço de trabalho |
Exemplo de conexão do SDK do cliente AOQ
clientIp é um campo opcional no corpo da solicitação. Se não for especificado, o endereço IP que solicita o QwenCloud gateway é usado como o IP do cliente. Se especificado, o valor clientIp terá precedência. Faça com que o AppServer da sua empresa obtenha o endereço IP real do cliente e o transmita para obter o melhor ponto de acesso Relay.
iOS (Swift)
```swift
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)
```
Android (Java)
```java
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);
```
OHOS (ArkTS)
```javascript
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);
```
Autenticação do protocolo WebRTC
O WebRTC conclui a troca SDP por meio de uma solicitação HTTP POST e a autenticação ocorre neste estágio. O cliente envia o SDP de oferta ao servidor e o servidor retorna o SDP de resposta.
| Item | Valor | Descrição |
|---|---|---|
| Método de solicitação | POSTAR | - |
| URL de solicitação | https://{endpoint}/api/v1/webrtc/realtime?model={model_name} |
Substitua endpoint e model_name. O URL de conexão varia de acordo com o modelo. Para obter detalhes, consulte Conexão WebRTC |
| Tipo de conteúdo | application/sdp |
O corpo da solicitação é uma string SDP |
| Autorização | Bearer $DASHSCOPE_API_KEY |
Sua chave API |
| Resposta | HTTP 200 com a resposta SDP | Retorna um código de status 4xx em caso de falha |
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 });
Autenticação do protocolo WebSocket
WebSocket possui a autenticação mais simples: envie a chave API em um cabeçalho HTTP ao estabelecer a conexão.
| Item | Valor | Descrição |
|---|---|---|
| URL de conexão | wss://maas.qwencloudapi.com/api-ws/v1/realtime?model={model_name} |
O URL de conexão varia de acordo com o modelo. Para obter detalhes, consulte Conexão WebSocket |
| Autorização | Bearer $DASHSCOPE_API_KEY |
Sua chave API |
import websocket, os
API_KEY = os.getenv("DASHSCOPE_API_KEY")
URL = "wss://maas.qwencloudapi.com/api-ws/v1/realtime?model=qwen3.5-omni-plus-realtime"
ws = websocket.WebSocketApp(URL, header=["Authorization: Bearer " + API_KEY])
ws.run_forever()