Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek obsahuje osvědčené postupy pro správu tokenů přístupu uživatelů v sadách SDK služeb Azure Communication Services. Podle těchto pokynů optimalizujte prostředky používané vaší aplikací a snižte počet přístupů k API služby Azure Communication Identity.
Přihlašovací údaje komunikačního tokenu
Komunikační tokenové přihlašovací údaje (Credential) jsou základním prvkem ověřování, který obalí přístupové tokeny uživatele. Používá se k ověřování uživatelů v komunikačních službách, jako je chat nebo volání. Kromě toho poskytuje integrované funkce aktualizace tokenů pro pohodlí vývojáře.
Výběr trvání relace
V závislosti na vašem scénáři můžete chtít upravit životnost tokenů vydaných pro vaši aplikaci. Následující osvědčené postupy nebo jejich kombinace vám můžou pomoct dosáhnout optimálního řešení pro váš scénář:
- Přizpůsobte si čas vypršení platnosti tokenu podle vašich konkrétních potřeb.
- Inicializujte přihlašovací údaje statickým tokenem pro jednorázové chatové zprávy nebo časově omezené relace hovorů.
- Funkci zpětného volání použijte pro agenty používající aplikaci delší dobu.
Nastavení vlastního času vypršení platnosti tokenu
Při vyžádání nového tokenu doporučujeme používat krátké tokeny životnosti pro jednorázové chatové zprávy nebo časově omezené hovory. Doporučujeme delší životnost tokenů pro agenty, kteří používají aplikaci po delší dobu. Výchozí doba vypršení platnosti tokenu je 24 hodin. Dobu vypršení platnosti můžete přizpůsobit zadáním hodnoty mezi hodinou a 24 hodinami na volitelný parametr následujícím způsobem:
const tokenOptions = { tokenExpiresInMinutes: 60 };
const user = { communicationUserId: userId };
const scopes = ["chat"];
let communicationIdentityToken = await identityClient.getToken(user, scopes, tokenOptions);
Statický token
V případě krátkodobých klientů inicializujete přihlašovací údaje statickým tokenem. Tento přístup je vhodný pro scénáře, jako je odesílání jednorázových zpráv v chatu nebo časově omezené relace volání.
let communicationIdentityToken = await identityClient.getToken({ communicationUserId: userId }, ["chat", "voip"]);
const tokenCredential = new AzureCommunicationTokenCredential(communicationIdentityToken.token);
Funkce zpětného volání
U dlouhodobých klientů inicializujete přihlašovací údaje pomocí funkce zpětného volání, která zajišťuje nepřetržitý stav ověřování během komunikace. Tento přístup je vhodný například pro dlouhé hovorové relace.
const tokenCredential = new AzureCommunicationTokenCredential({
tokenRefresher: async (abortSignal) => fetchTokenFromMyServerForUser(abortSignal, "<user_name>")
});
Aktualizace tokenů
Aby se správně implementovalo zpětné volání pro obnovení tokenu, musí kód vrátit řetězec s platným webovým tokenem JSON (JWT). Vrácený token musí být vždy platný a datum vypršení platnosti nastavené v budoucnu. Některé platformy, jako je JavaScript a .NET, nabízejí způsob, jak operaci aktualizace přerušit a předat funkci buď AbortSignal nebo CancellationToken. Doporučujeme, abyste tyto objekty přijali, využili je nebo je předali dál.
Příklad 1: Aktualizace tokenu pro komunikačního uživatele
Předpokládejme, že máme aplikaci Node.js postavenou na Expressu /getToken s koncovým bodem, který umožňuje načíst nový platný token pro uživatele určeného názvem.
app.post('/getToken', async (req, res) => {
// Custom logic to determine the communication user id
let userId = await getCommunicationUserIdFromDb(req.body.username);
// Get a fresh token
const identityClient = new CommunicationIdentityClient("<COMMUNICATION_SERVICES_CONNECTION_STRING>");
let communicationIdentityToken = await identityClient.getToken({ communicationUserId: userId }, ["chat", "voip"]);
res.json({ communicationIdentityToken: communicationIdentityToken.token });
});
Dále musíme implementovat zpětné volání pro obnovení tokenu v klientské aplikaci, správně využít AbortSignal a vrátit rozbalený řetězec JWT.
const fetchTokenFromMyServerForUser = async function (abortSignal, username) {
const response = await fetch(`${HOST_URI}/getToken`,
{
method: "POST",
body: JSON.stringify({ username: username }),
signal: abortSignal,
headers: { 'Content-Type': 'application/json' }
});
if (response.ok) {
const data = await response.json();
return data.communicationIdentityToken;
}
};
Příklad 2: Aktualizace tokenu pro uživatele Teams
Předpokládejme, že máme aplikaci Node.js postavenou na Expressu /getTokenForTeamsUser s koncovým bodem, který umožňuje vyměnit přístupový token Microsoft Entra uživatele Teams za nový přístupový token identity komunikace s odpovídajícím časem vypršení platnosti.
app.post('/getTokenForTeamsUser', async (req, res) => {
const identityClient = new CommunicationIdentityClient("<COMMUNICATION_SERVICES_CONNECTION_STRING>");
let communicationIdentityToken = await identityClient.getTokenForTeamsUser(req.body.teamsToken, '<AAD_CLIENT_ID>', '<TEAMS_USER_OBJECT_ID>');
res.json({ communicationIdentityToken: communicationIdentityToken.token });
});
Dále musíme implementovat zpětné volání pro obnovu tokenu v klientské aplikaci, které má za úkol:
- Aktualizujte přístupový token Microsoft Entra uživatele Teams.
- Vyměňte přístupový token Microsoft Entra uživatele Teams pro přístupový token komunikační identity.
const fetchTokenFromMyServerForUser = async function (abortSignal, username) {
// 1. Refresh the Azure AD access token of the Teams User
let teamsTokenResponse = await refreshAadToken(abortSignal, username);
// 2. Exchange the Azure AD access token of the Teams User for a Communication Identity access token
const response = await fetch(`${HOST_URI}/getTokenForTeamsUser`,
{
method: "POST",
body: JSON.stringify({ teamsToken: teamsTokenResponse.accessToken }),
signal: abortSignal,
headers: { 'Content-Type': 'application/json' }
});
if (response.ok) {
const data = await response.json();
return data.communicationIdentityToken;
}
}
V tomto příkladu použijeme knihovnu MICROSOFT Authentication Library (MSAL) k aktualizaci přístupového tokenu Microsoft Entra. Podle průvodce získáním tokenu Microsoft Entra pro volání rozhraní API se nejprve pokusíme získat token bez zásahu uživatele. Pokud to není možné, aktivujeme jeden z interaktivních toků.
const refreshAadToken = async function (abortSignal, username) {
if (abortSignal.aborted === true) throw new Error("Operation canceled");
// MSAL.js v2 exposes several account APIs; the logic to determine which account to use is the responsibility of the developer.
// In this case, we'll use an account from the cache.
let account = (await publicClientApplication.getTokenCache().getAllAccounts()).find(u => u.username === username);
const renewRequest = {
scopes: [
"https://auth.msft.communication.azure.com/Teams.ManageCalls",
"https://auth.msft.communication.azure.com/Teams.ManageChats"
],
account: account,
forceRefresh: forceRefresh
};
let tokenResponse = null;
// Try to get the token silently without the user's interaction
await publicClientApplication.acquireTokenSilent(renewRequest).then(renewResponse => {
tokenResponse = renewResponse;
}).catch(async (error) => {
// In case of an InteractionRequired error, send the same request in an interactive call
if (error instanceof InteractionRequiredAuthError) {
// You can choose the popup or redirect experience (`acquireTokenPopup` or `acquireTokenRedirect` respectively)
publicClientApplication.acquireTokenPopup(renewRequest).then(function (renewInteractiveResponse) {
tokenResponse = renewInteractiveResponse;
}).catch(function (interactiveError) {
console.log(interactiveError);
});
}
});
return tokenResponse;
}
Poskytnutí počátečního tokenu
Pokud chcete kód dále optimalizovat, můžete token načíst při spuštění aplikace a předat ho přímo přihlašovacím údajům. Poskytnutí počátečního tokenu přeskočí první volání funkce zpětného volání refresheru při zachování všech následných volání.
const tokenCredential = new AzureCommunicationTokenCredential({
tokenRefresher: async () => fetchTokenFromMyServerForUser("<user_id>"),
token: "<initial_token>"
});
Proaktivní aktualizace tokenů
Použijte proaktivní aktualizaci, aby se odstranilo případné zpoždění při načítání tokenu na vyžádání. Proaktivní proces aktualizace obnovuje token na pozadí na konci jeho životnosti. Když platnost tokenu brzy vyprší, 10 minut před koncem platnosti se přihlašovací údaje začnou pokoušet o načtení tokenu. Spouští zpětné volání se zvyšující se frekvencí, dokud se to nepodaří a nezíská token s dostatečnou platností.
const tokenCredential = new AzureCommunicationTokenCredential({
tokenRefresher: async () => fetchTokenFromMyServerForUser("<user_id>"),
refreshProactively: true
});
Pokud chcete zrušit naplánované úlohy aktualizace, odstraňte objekt Credential.
Proaktivní aktualizace tokenu pro uživatele Teams
Pokud chcete minimalizovat počet volání rozhraní API služby Azure Communication Identity, ujistěte se, že token Microsoft Entra, který předáváte pro výměnu, má dostatečnou platnost (alespoň > 10 minutami). V případě, že msAL vrátí token uložený v mezipaměti s kratší platností, máte následující možnosti pro obejití mezipaměti:
- Vynucená aktualizace tokenu
- Zvýšení intervalu pro prodloužení platnosti tokenu MSAL na více než 10 minut
Možnost 1: Aktivujte tok získání tokenu s AuthenticationParameters.forceRefresh nastaveným na true.
// Extend the `refreshAadToken` function
const refreshAadToken = async function (abortSignal, username) {
// ... existing refresh logic
// Make sure the token has at least 10-minute lifetime and if not, force-renew it
if (tokenResponse.expiresOn < (Date.now() + (10 * 60 * 1000))) {
const renewRequest = {
scopes: [
"https://auth.msft.communication.azure.com/Teams.ManageCalls",
"https://auth.msft.communication.azure.com/Teams.ManageChats"
],
account: account,
forceRefresh: true // Force-refresh the token
};
await publicClientApplication.acquireTokenSilent(renewRequest).then(renewResponse => {
tokenResponse = renewResponse;
});
}
}
Možnost 2: Inicializace kontextu ověřování MSAL vytvořením instance PublicClientApplication vlastní SystemOptions.tokenRenewalOffsetSeconds.
const publicClientApplication = new PublicClientApplication({
system: {
tokenRenewalOffsetSeconds: 900 // 15 minutes (by default 5 minutes)
});
Zrušení aktualizace
Aby klienti komunikace mohli zrušit probíhající úlohy aktualizace, je nutné předat objekt zrušení do zpětného volání aktualizačního nástroje. Tento vzor platí jenom pro JavaScript a .NET.
var controller = new AbortController();
var joinChatBtn = document.querySelector('.joinChat');
var leaveChatBtn = document.querySelector('.leaveChat');
joinChatBtn.addEventListener('click', function () {
// Wrong:
const tokenCredentialWrong = new AzureCommunicationTokenCredential({
tokenRefresher: async () => fetchTokenFromMyServerForUser("<user_name>")
});
// Correct: Pass abortSignal through the arrow function
const tokenCredential = new AzureCommunicationTokenCredential({
tokenRefresher: async (abortSignal) => fetchTokenFromMyServerForUser(abortSignal, "<user_name>")
});
// ChatClient is now able to abort token refresh tasks
const chatClient = new ChatClient("<endpoint-url>", tokenCredential);
// Pass the abortSignal to the chat client through options
const createChatThreadResult = await chatClient.createChatThread(
{ topic: "Hello, World!" },
{
// ...
abortSignal: controller.signal
}
);
// ...
});
leaveChatBtn.addEventListener('click', function() {
controller.abort();
console.log('Leaving chat...');
});
Pokud chcete zrušit následné úlohy aktualizace, odstraňte objekt Credential.
Vyčištění prostředků
Vzhledem k tomu, že objekt Credential lze předat více instancím klienta chatu nebo volání, sada SDK nepředpokládá žádné předpoklady o jeho životnosti a ponechá odpovědnost za její likvidaci vývojáři. Je na aplikacích komunikačních služeb, aby vyřadily instanci přihlašovacích údajů, když již není potřeba. Zrušení přihlašovacích údajů také zruší naplánované akce aktualizace, když je aktivní aktualizace povolená.
Volejte .dispose() funkci.
const tokenCredential = new AzureCommunicationTokenCredential("<token>");
// Use the credential for Calling or Chat
const chatClient = new ChatClient("<endpoint-url>", tokenCredential);
// ...
tokenCredential.dispose()
Zpracování odhlášení
V závislosti na vašem scénáři můžete chtít uživatele odhlásit z jedné nebo více služeb:
- Pokud chcete uživatele odhlásit z jedné služby, odstraňte objekt Credential.
- Pokud se chcete odhlásit uživatele z více služeb, implementujte signalizační mechanismus, který informuje všechny služby o odstranění objektu Credential a navíc odvolá všechny přístupové tokeny pro danou identitu.
Další kroky
Tento článek popisuje, jak:
- Správně inicializovat a odstranit objekt Credential
- Implementace zpětného volání obnovovače tokenu
- Optimalizace logiky aktualizace tokenu