Logga in användare

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ån idTokenClaims för ett account-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 username egenskap (rekommenderas inte)
    • Som ID-tokenanspråk för kontoobjektet upn (rekommenderas inte)

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:

  1. Ladda skriptet för omdirigeringsbryggan – Det här skriptet hanterar kommunikationen med huvudfönstret
  2. Inkludera inte javascript förutom bridge-skript – Omdirigeringssidan ska bara köra bryggskriptet
  3. Inkludera inte routningslogik – Undvik routerbibliotek som kan störa hashhantering
  4. 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:

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_progress uppstå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!