Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
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 dariidTokenClaimssuatu objekaccount) -
login_hint(dapat diambil dengan cara berikut)- Sebagai properti
loginHintmilik objek akun (disarankan) - Sebagai klaim token ID objek akun
login_hint(disarankan) - Sebagai properti objek
usernameakun (tidak disarankan) - Sebagai klaim token ID dari objek akun
upn(tidak disarankan)
- Sebagai properti
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:
- Muat skrip jembatan pengalihan - Skrip ini menangani komunikasi dengan jendela utama
- Tidak menyertakan JavaScript apa pun kecuali untuk skrip penghubung - Halaman pengalihan hanya boleh menjalankan skrip penghubung
- Tidak termasuk logika perutean - Hindari pustaka router yang mungkin mengganggu penanganan hash
- 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:
- Sampel Ekspres — Menunjukkan implementasi JavaScript dengan CSS kustom
- Sampel React Router — Menunjukkan implementasi React dengan komponen Material-UI
Kedua sampel menunjukkan:
- Pesan peringatan ditampilkan selama autentikasi popup
- Coba lagi modal/dialog dengan penjelasan yang jelas ketika
interaction_in_progressterjadi 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!