Masuk sebagai pengguna

Sebelum memulai di sini, pastikan Anda memahami cara menginisialisasi objek aplikasi.

API masuk di MSAL memperoleh authorization code yang dapat ditukarkan dengan token ID untuk pengguna yang sudah masuk, sembari memberikan persetujuan untuk cakupan izin bagi sumber daya tambahan, serta token akses yang berisi cakupan izin yang telah disetujui pengguna, yang memungkinkan aplikasi Anda memanggil API secara aman.

Memilih Jenis Interaksi

Lihat di sini jika Anda tidak yakin tentang perbedaan antara loginRedirect dan loginPopup.

Masuk pengguna

Anda harus meneruskan objek permintaan ke API login. Objek ini memungkinkan Anda menggunakan parameter yang berbeda dalam permintaan. Lihat di sini untuk informasi selengkapnya tentang parameter objek permintaan.

Untuk permintaan masuk, semua parameter bersifat opsional, sehingga Anda dapat mengirim objek kosong.

  • Popup
try {
    const loginResponse = await msalInstance.loginPopup({});
} catch (err) {
    // handle error
}
  • Redirect
try {
    msalInstance.loginRedirect({});
} catch (err) {
    // handle error
}

Atau Anda dapat mengirim serangkaian izin akses untuk persetujuan awal:

  • 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
}

API Akun

Ketika panggilan masuk berhasil, Anda dapat menggunakan getAllAccounts() fungsi untuk mengambil informasi tentang pengguna yang saat ini masuk.

const myAccounts: AccountInfo[] = msalInstance.getAllAccounts();

Jika Anda mengetahui informasi akun, Anda juga dapat mengambil informasi akun dengan menggunakan getAccount() API:

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

Pemfilteran dengan username disediakan untuk kenyamanan dan harus dianggap kurang dapat diandalkan daripada pencarian berdasarkan homeAccountId. Jika memungkinkan, gunakan homeAccountId.

Dalam skenario B2C, tenant B2C Anda perlu dikonfigurasi untuk mengembalikan klaim emails pada idTokens agar dapat menggunakan filter username pada API getAccount().

API ini akan mengembalikan objek akun atau array objek akun dengan tanda tangan berikut:

{
    // 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;
};

Masuk senyap dengan ssoSilent()

Jika Anda sudah memiliki sesi yang ada dengan server autentikasi, Anda dapat menggunakan API ssoSilent() untuk membuat permintaan token tanpa interaksi.

Dengan Petunjuk Pengguna

Jika Anda sudah memiliki informasi masuk pengguna, Anda dapat meneruskan ini ke API untuk meningkatkan performa dan memastikan bahwa server otorisasi akan mencari sesi akun yang benar. Anda dapat meneruskan salah satu hal berikut ke objek permintaan agar berhasil mendapatkan token secara diam-diam.

Disarankan untuk memanfaatkan login_hint klaim token ID opsional (disediakan untuk ssoSilent sebagai loginHint), karena ini merupakan petunjuk akun yang paling andal untuk permintaan senyap (dan interaktif).

  • account (yang dapat diambil menggunakan salah satu API akun)
  • sid (yang dapat diambil dari idTokenClaims suatu objek account)
  • login_hint (dapat diambil dengan cara berikut)
    • Sebagai properti loginHint milik objek akun (disarankan)
    • Sebagai klaim token ID objek akun login_hint (disarankan)
    • Sebagai properti objek username akun (tidak disarankan)
    • Sebagai klaim token ID dari objek akun upn (tidak disarankan)

Note

Properti username dan upn didukung sebagian sebagai pengganti klaim login_hint yang sebenarnya, tetapi tidak direkomendasikan. Gunakan properti akun loginHint atau idTokenClaims.login_hint jika tersedia.

Meneruskan akun akan mencari login_hint klaim token ID opsional (lebih disukai), lalu sid klaim token id opsional, lalu kembali ke loginHint (jika disediakan) atau nama pengguna akun.

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
    }
}

Tanpa Petunjuk Pengguna

Jika tidak ada cukup informasi yang tersedia tentang pengguna, Anda dapat mencoba menggunakan ssoSilent API tanpa melewati account, sid atau login_hint.

const silentRequest = {
    scopes: ["User.Read", "Mail.Read"]
};

Namun, ketahuilah bahwa jika aplikasi Anda memiliki jalur kode untuk beberapa pengguna dalam satu sesi browser, atau jika pengguna memiliki beberapa akun untuk sesi browser tunggal tersebut, maka ada kemungkinan kesalahan masuk senyap yang lebih tinggi. Anda mungkin melihat kesalahan berikut muncul jika server otorisasi menemukan beberapa sesi akun:

InteractionRequiredAuthError: interaction_required: AADSTS16000: Either multiple user identities are available for the current request or selected account is not supported for the scenario.

Ini menunjukkan bahwa server tidak dapat menentukan akun mana yang akan masuk, dan akan memerlukan salah satu parameter di atas (account, , login_hint) sidatau rincian masuk interaktif untuk memilih akun.

Warning

Saat menggunakan ssoSilent, layanan mencoba memuat halaman URI pengalihan Anda di iframe yang disematkan secara tidak terlihat. Kebijakan keamanan konten dan nilai header HTTP yang ada dalam respons halaman URI pengalihan aplikasi Anda, seperti X-FRAME-OPTIONS: DENY dan X-FRAME-OPTIONS: SAMEORIGIN, dapat mencegah aplikasi Anda memuat di iframe, secara efektif memblokir SSO senyap. Jika Anda ingin menggunakan ssoSilent, pastikan URI pengalihan menunjuk ke halaman yang tidak menerapkan kebijakan tersebut.

Pertimbangan RedirectUri

Semua alur autentikasi sekarang memerlukan halaman pengalihan khusus yang mengimplementasikan jembatan pengalihan MSAL. Ini diperlukan untuk mendukung header COOP (Cross-Origin-Opener-Policy) dan memungkinkan komunikasi yang aman antara jendela popup/iframe dan aplikasi utama.

Menyiapkan halaman pengalihan

Anda redirectUri harus menunjuk ke halaman khusus yang memuat skrip jembatan pengalihan. Halaman ini harus:

  1. Muat skrip jembatan pengalihan - Skrip ini menangani komunikasi dengan jendela utama
  2. Tidak menyertakan JavaScript apa pun kecuali untuk skrip penghubung - Halaman pengalihan hanya boleh menjalankan skrip penghubung
  3. Tidak termasuk logika perutean - Hindari pustaka router yang mungkin mengganggu penanganan hash
  4. Terdaftar di Pendaftaran Aplikasi Anda - URI harus sama persis dengan apa yang terdaftar di portal Azure

Contoh halaman pengalihan (saat menggunakan bunder seperti Vite atau 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

Specifier @azure/msal-browser/redirect-bridge harus di-resolve oleh bundler (Vite, Webpack, dll.) — itu bukan URL yang bisa diminta langsung oleh browser. Untuk instruksi khusus kerangka kerja, lihat panduan penyiapan Jembatan Pengalihan.

Konfigurasi

Anda dapat mengatur redirectUri secara global dalam konfigurasi MSAL Anda atau berdasarkan per permintaan:

Konfigurasi global:

const msalConfig = {
    auth: {
        clientId: "your-client-id",
        authority: "https://login.microsoftonline.com/common",
        redirectUri: "http://localhost:3000/redirect"
    }
};

const msalInstance = new PublicClientApplication(msalConfig);

Konfigurasi per permintaan:

msalInstance.loginPopup({
    scopes: ["user.read"],
    redirectUri: "http://localhost:3000/redirect"
});

Untuk informasi selengkapnya dan implementasi sampel lengkap, lihat:

Menangani kesalahan popup interaction_in_progress

Untuk alur popup, Anda dapat menggunakan flag overrideInteractionInProgress untuk membatalkan interaksi yang masih tertunda dan memulai interaksi baru. Ini berguna untuk skenario pemulihan di mana pengguna membatalkan popup atau interaksi gagal.

Note

Fitur ini hanya tersedia untuk alur popup dan tidak didukung untuk alur pengalihan. Dengan header COOP (Cross-Origin-Opener-Policy), koneksi tradisional window.opener diputus, sehingga jendela pop-up hanya dapat berkomunikasi dengan frame utama melalui BroadcastChannel.

Important

Mengatur ini ke true akan secara paksa membatalkan permintaan autentikasi popup yang tertunda tetapi tidak akan menutup popup terbuka apa pun.

Ketika diatur ke true:

  • Jika interaksi popup lain saat ini sedang berlangsung, interaksi tersebut dibatalkan secara paksa tetapi popup terbuka apa pun tidak ditutup
  • Interaksi tertunda ditolak dengan kesalahan interaction_in_progress_cancelled
  • Alur pop-up baru langsung berjalan

Kasus penggunaan yang valid:

  • Memulihkan dari kesalahan saat pengguna membatalkan popup (popup ditutup tanpa menyelesaikan autentikasi)
  • Menerapkan alur pemulihan kesalahan kustom
  • Menyediakan mekanisme "coba lagi" setelah interaksi popup gagal

Default:false

Penting: Hanya gunakan saat tombol diklik

Jangan coba lagi secara otomatis saat menangkap kesalahan interaction_in_progress . Pengesampingan seharusnya hanya dipicu oleh tindakan eksplisit dari pengguna (seperti mengklik tombol "Coba Lagi"). Mengesampingkan interaksi secara otomatis dapat menyebabkan:

  • Kondisi balapan antara beberapa alur autentikasi
  • Pembatalan tak terduga dari upaya autentikasi yang sah
  • Pengalaman pengguna yang buruk dengan alur autentikasi dimulai dan dihentikan secara tak terduga
  • Terlalu banyak jendela pop-up terbuka yang tidak menghasilkan respons autentikasi yang berhasil

Contoh: Penanganan kesalahan yang tepat dengan coba ulang yang dipicu oleh pengguna

Untuk implementasi lengkap dengan umpan balik visual, lihat:

Kedua sampel menunjukkan:

  • Pesan peringatan ditampilkan selama autentikasi popup
  • Coba lagi modal/dialog dengan penjelasan yang jelas ketika interaction_in_progress terjadi kesalahan
  • Pengelolaan status yang tepat untuk percobaan ulang yang dipicu oleh pengguna
  • Komponen UI siap produksi
// 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
}

Contoh: Komponen React dengan percobaan ulang yang dipicu oleh pengguna

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>
    );
}

Langkah Selanjutnya

Pelajari cara memperoleh dan menggunakan token akses!