Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Innan du börjar här bör du se till att du förstår hur du initierar programobjektet.
Inloggnings-API:erna i MSAL hämtar en authorization code som kan bytas ut mot en ID-token för en inloggad användare, samtidigt som du godkänner omfång för ytterligare en resurs och en åtkomsttoken som innehåller de användarmedgivande omfången så att din app kan anropa API:et på ett säkert sätt.
Välja en interaktionstyp
Se här om du är osäker på skillnaderna mellan loginRedirect och loginPopup.
Logga in användaren
Du måste skicka ett begärandeobjekt till inloggnings-API:erna. Med det här objektet kan du använda olika parametrar i begäran. Mer information om parametrarna för begärandeobjekt finns här .
För inloggningsbegäranden är alla parametrar valfria, så du kan bara skicka ett tomt objekt.
- Popup
try {
const loginResponse = await msalInstance.loginPopup({});
} catch (err) {
// handle error
}
- Redirect
try {
msalInstance.loginRedirect({});
} catch (err) {
// handle error
}
Eller så kan du skicka en uppsättning behörigheter för att förhandsgodkänna till:
- Popup
var loginRequest = {
scopes: ["user.read", "mail.send"] // optional Array<string>
};
try {
const loginResponse = await msalInstance.loginPopup(loginRequest);
} catch (err) {
// handle error
}
- Redirect
var loginRequest = {
scopes: ["user.read", "mail.send"] // optional Array<string>
};
try {
msalInstance.loginRedirect(loginRequest);
} catch (err) {
// handle error
}
Konto-API:er
När ett inloggningsanrop har slutförts kan du använda getAllAccounts() funktionen för att hämta information om användare som är inloggade.
const myAccounts: AccountInfo[] = msalInstance.getAllAccounts();
Om du känner till kontoinformationen kan du också hämta kontoinformationen med hjälp av API:et getAccount() :
const username = "test@contoso.com";
const myAccount: AccountInfo = msalInstance.getAccount({ username });
const homeAccountId = "userid.hometenantid"; // Best to retrieve the homeAccountId from an account object previously obtained through msal
const myAccount: AccountInfo = msalInstance.getAccount({ homeAccountId });
Note
Filtrering efter username tillhandahålls för enkelhetens skull och bör betraktas som mindre tillförlitlig än sökning baserad på homeAccountId. När det är möjligt, använd homeAccountId.
I B2C-scenarier måste B2C-klientorganisationen konfigureras så att anspråket emails returneras på idTokens för att kunna använda filtret username på API:et getAccount().
Dessa API:er returnerar ett kontoobjekt eller en matris med kontoobjekt med följande signatur:
{
// home account identifier for this account object
homeAccountId: string;
// Entity who issued the token represented as a full host of it (e.g. login.microsoftonline.com)
environment: string;
// Full tenant or organizational id that this account belongs to
tenantId: string;
// preferred_username claim of the id_token that represents this account.
username: string;
};
Tyst inloggning med ssoSilent()
Om du redan har en session som finns med autentiseringsservern kan du använda API:et ssoSilent() för att göra begäranden om token utan interaktion.
Med användartips
Om du redan har användarens inloggningsinformation kan du skicka detta till API:et för att förbättra prestanda och se till att auktoriseringsservern söker efter rätt kontosession. Du kan skicka in något av följande i begäranobjektet för att hämta en token utan användarinteraktion.
Vi rekommenderar att du använder det valfria ID-tokenanspråketlogin_hint (tillhandahålls till ssoSilent som loginHint), eftersom det är den mest tillförlitliga kontointydningen av tysta (och interaktiva) begäranden.
-
account(som kan hämtas med något av konto-API:erna) -
sid(som kan hämtas frånidTokenClaimsför ettaccount-objekt) -
login_hint(kan hämtas på följande sätt)- Som kontoobjektets
loginHint-egenskap (rekommenderas) - Som ID-tokenanspråk för kontoobjektet
login_hint(rekommenderas) - Som kontoobjektets
usernameegenskap (rekommenderas inte) - Som ID-tokenanspråk för kontoobjektet
upn(rekommenderas inte)
- Som kontoobjektets
Note
Egenskaperna username och upn stöds delvis i stället för det faktiska login_hint anspråket, men de rekommenderas inte. Använd loginHint eller idTokenClaims.login_hint kontots egenskaper om de är tillgängliga.
Om du skickar ett konto letar du efter det login_hint valfria ID-tokenanspråket (rekommenderas), sedan det valfria ID-tokenanspråket sid och återgår sedan till loginHint (om det tillhandahålls) eller kontots användarnamn.
const account = msalInstance.getAllAccounts()[0];
const silentRequest = {
scopes: ["User.Read", "Mail.Read"],
loginHint: account.loginHint, // alternatively, account.idTokenClaims.login_hint
};
try {
const loginResponse = await msalInstance.ssoSilent(silentRequest);
} catch (err) {
if (err instanceof InteractionRequiredAuthError) {
const loginResponse = await msalInstance.loginPopup(silentRequest).catch(error => {
// handle error
});
} else {
// handle error
}
}
Utan användartips
Om det inte finns tillräckligt med information om användaren kan du försöka använda API:et ssoSilentutan att skicka en account, sid eller login_hint.
const silentRequest = {
scopes: ["User.Read", "Mail.Read"]
};
Tänk dock på att om ditt program har kodsökvägar för flera användare i en enda webbläsarsession, eller om användaren har flera konton för den enskilda webbläsarsessionen, finns det en högre sannolikhet för tyst inloggningsfel. Du kan se följande fel visas om flera kontosessioner hittas av auktoriseringsservern:
InteractionRequiredAuthError: interaction_required: AADSTS16000: Either multiple user identities are available for the current request or selected account is not supported for the scenario.
Detta anger att servern inte kunde avgöra vilket konto som ska loggas in och kräver antingen någon av parametrarna ovan (account, login_hint, sid) eller en interaktiv inloggning för att välja kontot.
Varning
När du använder ssoSilentförsöker tjänsten läsa in omdirigerings-URI-sidan i en osynlig inbäddad iframe. Innehållssäkerhetsprinciper och HTTP-huvudvärden som finns i svaret från appens sida för omdirigerings-URI:n, till exempel X-FRAME-OPTIONS: DENY och X-FRAME-OPTIONS: SAMEORIGIN, kan förhindra att din app läses in i en iframe, vilket i praktiken blockerar tyst enkel inloggning (SSO). Om du tänker använda ssoSilentkontrollerar du att omdirigerings-URI:n pekar på en sida som inte implementerar några sådana principer.
Överväganden för RedirectUri
Alla autentiseringsflöden kräver nu en dedikerad omdirigeringssida som implementerar MSAL-omdirigeringsbryggan. Detta är nödvändigt för att stödja COOP-huvuden (Cross-Origin-Opener-Policy) och aktivera säker kommunikation mellan popup-/iframe-fönster och huvudprogrammet.
Konfigurera omdirigeringssidan
Ditt redirectUri måste peka på en dedikerad sida som laddar skriptet för omdirigeringsbryggan. Den här sidan bör:
- Ladda skriptet för omdirigeringsbryggan – Det här skriptet hanterar kommunikationen med huvudfönstret
- Inkludera inte javascript förutom bridge-skript – Omdirigeringssidan ska bara köra bryggskriptet
- Inkludera inte routningslogik – Undvik routerbibliotek som kan störa hashhantering
- Vara registrerad i din appregistrering – URI:n måste matcha exakt det som är registrerat i Azure-portalen
Exempel på omdirigeringssida (när du använder en paketerare som Vite eller Webpack):
<!DOCTYPE html>
<html>
<head>
<title>Redirect</title>
</head>
<body>
<p>Processing authentication...</p>
<script type="module">
import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";
broadcastResponseToMainFrame();
</script>
</body>
</html>
Note
Angivelsen @azure/msal-browser/redirect-bridge måste lösas upp av ett byggverktyg (Vite, Webpack osv.) – det är inte en URL som webbläsare kan hämta direkt. Ramverksspecifika instruktioner finns i installationsguiden för omdirigeringsbryggan.
Configuration
Du kan ange redirectUri globalt i MSAL-konfigurationen eller per begäran:
Global konfiguration:
const msalConfig = {
auth: {
clientId: "your-client-id",
authority: "https://login.microsoftonline.com/common",
redirectUri: "http://localhost:3000/redirect"
}
};
const msalInstance = new PublicClientApplication(msalConfig);
Konfiguration per begäran:
msalInstance.loginPopup({
scopes: ["user.read"],
redirectUri: "http://localhost:3000/redirect"
});
Mer information och fullständiga exempelimplementeringar finns i:
Hantera popup-fel interaction_in_progress
För popup-flöden kan du använda overrideInteractionInProgress flaggan för att avbryta en väntande interaktion och starta en ny. Detta är användbart för återställningsscenarier där användaren avbröt ett popup-fönster eller en interaktion misslyckades.
Note
Den här funktionen är endast tillgänglig för popup-flöden och stöds inte för omdirigeringsflöden. Med COOP-huvudet (Cross-Origin-Opener-Policy) är den traditionella window.opener anslutningen avskuren, vilket gör att popup-fönster endast kan kommunicera med huvudramen via BroadcastChannel.
Important
Om du ställer in detta på true tvingar det fram avbrott av alla väntande popup-begäranden om autentisering, men stänger inte några öppna popup-fönster.
När det är inställt på true:
- Om en annan popup-interaktion pågår avbryts den med kraft, men alla öppna popup-fönster stängs inte
- Den väntande interaktionen avvisas med ett
interaction_in_progress_cancelled-fel - Det nya popup-flödet fortsätter omedelbart
Giltiga användningsfall:
- Återställning från fel där användaren avbröt ett popup-fönster (popup-fönstret stängdes utan att autentiseringen slutfördes)
- Implementera anpassade felåterställningsflöden
- Tillhandahålla en mekanism för "återförsök" efter en misslyckad popup-interaktion
Standard:false
Viktigt: Använd endast vid knappklick
Försök inte igen automatiskt när du får ett interaction_in_progress fel. Åsidosättningen ska bara utlösas av en explicit användaråtgärd (till exempel genom att klicka på knappen Försök igen). Att automatiskt åsidosätta interaktioner kan leda till:
- Konkurrensförhållanden mellan flera autentiseringsflöden
- Oväntade annulleringar av legitima autentiseringsförsök
- Dålig användarupplevelse med autentiseringsflöden som startar och stoppas oväntat
- Många öppna popupfönster som inte leder till ett lyckat autentiseringssvar
Exempel: Korrekt felhantering med försök igen som utlöses av användaren
Fullständiga implementeringar med visuell feedback finns i:
- Express-exempel – Demonstrerar JavaScript-implementering med anpassad CSS
- React Router-exempel – Demonstrerar React-implementering med Material-UI komponenter
Båda exemplen visar:
- Varningsmeddelande som visas under popup-autentisering
- Försök igen med modal/dialogruta med en tydlig förklaring när felet
interaction_in_progressuppstår - Korrekt tillståndshantering för användarutlösta omförsök
- Produktionsklara gränssnittskomponenter
// State to track if user wants to retry
let userWantsRetry = false;
// Button click handler
async function handleLoginClick() {
try {
const loginRequest = {
scopes: ["user.read"]
};
// If user explicitly clicked retry, override the existing interaction
if (userWantsRetry) {
loginRequest.overrideInteractionInProgress = true;
userWantsRetry = false; // Reset flag
}
const response = await msalInstance.loginPopup(loginRequest);
// Handle successful login
} catch (error) {
if (error.errorCode === 'interaction_in_progress') {
// Show retry button to user - DO NOT automatically retry
showRetryButton();
} else {
// Handle other errors
console.error(error);
}
}
}
// Retry button click handler
function handleRetryClick() {
userWantsRetry = true; // Set flag for next login attempt
handleLoginClick(); // User explicitly requested retry
}
Exempel: React-komponent med nytt försök som utlöses av användaren
function LoginButton() {
const { instance } = useMsal();
const [showRetry, setShowRetry] = useState(false);
const [retryRequested, setRetryRequested] = useState(false);
const handleLogin = async () => {
try {
const loginRequest = {
scopes: ["user.read"],
// Only override if user clicked the retry button
overrideInteractionInProgress: retryRequested
};
setRetryRequested(false); // Reset retry flag
const response = await instance.loginPopup(loginRequest);
setShowRetry(false);
} catch (error) {
if (error.errorCode === 'interaction_in_progress') {
// Show retry button - let user decide whether to retry
setShowRetry(true);
} else {
console.error(error);
}
}
};
const handleRetry = () => {
setRetryRequested(true); // User explicitly requested retry
handleLogin();
};
return (
<div>
<button onClick={handleLogin}>Login</button>
{showRetry && (
<button onClick={handleRetry}>
Retry Login (Cancel Pending)
</button>
)}
</div>
);
}
Nästa steg
Lär dig hur du hämtar och använder en åtkomsttoken!