Panduan Migrasi dari MSAL v1 ke @azure/msal-react dan @azure/msal-browser

Artikel ini memberikan gambaran umum tentang migrasi dari MSAL v1 ke @azure/msal-react dan @azure/msal-browser. Kami merekomendasikan migrasi untuk meningkatkan performa dan keamanan yang lebih baik dengan alur kode otorisasi dengan PKCE dan Akses Bersyarat. Selain itu, ada dukungan aplikasi satu halaman yang lebih baik.

Prasyarat

  • Sebuah akun Azure dengan langganan aktif. Membuat akun secara gratis
  • Aplikasi yang ada yang terdaftar di tenant Microsoft Entra Anda.

Memperbarui pendaftaran aplikasi Anda

Pustaka @azure/msal-react adalah pembungkus untuk @azure/msal-browser yang menerapkan Alur Kode Otorisasi dengan PKCE. Ini adalah pembaruan signifikan dari pustaka MSAL v1 yang mengimplementasikan Alur Implisit.

Anda harus membuat pendaftaran aplikasi baru atau memperbarui yang sudah ada untuk menggunakan jenis baru redirectUri "SPA". Lihat Aplikasi satu halaman: Pendaftaran aplikasi untuk informasi selengkapnya.

Menginstal @azure/msal-react dan @azure/msal-browser

Baik @azure/msal-react maupun dependensi peer-nya, @azure/msal-browser, dapat diinstal dari npm. Penting untuk menghapus instalan paket MSAL lama Anda. Buka terminal dan jalankan perintah berikut.

npm uninstall msal
npm install @azure/msal-react @azure/msal-browser

Meningkatkan dari react-aad-msal

Jika aplikasi Anda saat ini menggunakan React Microsoft Entra MSAL untuk autentikasi dan Anda ingin bermigrasi ke @azure/msal-react bagian ini akan menguraikan perbedaan antara dua pustaka dan beberapa perubahan yang perlu Anda buat. React Microsoft Entra MSAL adalah pustaka pihak ketiga, dan karena MSAL React dibangun dari nol, mungkin ada beberapa kasus khusus yang belum dicakup atau didukung oleh MSAL React.

Berikut ini adalah fitur yang didukung di react-aad-msal mana tidak didukung di @azure/msal-react:

  • Memverifikasi kedaluwarsa IdToken sebelum merender komponen yang dilindungi & refresh otomatis IdToken yang kedaluwarsa
  • Dukungan siap pakai untuk redux store (alternatif di bawah ini)

Untuk kasus lain yang dimungkinkan dengan react-aad-msal tetapi tidak lagi dimungkinkan dengan @azure/msal-react, buat issue di repo GitHub microsoft-authentication-library-for-js.

Inisialisasi

Dalam react-aad-msal Anda menginisialisasi instans MSAL Anda dengan membuat MsalAuthProvider objek yang kemudian diteruskan ke AzureAD komponen.

import { MsalAuthProvider } from "react-aad-msal";

const authProvider = new MsalAuthProvider(config, authenticationParameters, options);

Dalam @azure/msal-react Anda menginisialisasi instans MSAL Anda menggunakan PublicClientApplication yang diekspor dari @azure/msal-browser yang kemudian diteruskan ke komponen yang MsalProvider diekspor dari @azure/msal-react. Opsi konfigurasi sebagian besar mirip antara msal dan @azure/msal-browser, namun Anda dapat merujuk ke jenis Konfigurasi untuk opsi konfigurasi terbaru.

Parameter authenticationParameters dan options yang digunakan react-aad-msal tidak digunakan dalam @azure/msal-react, meskipun fungsionalitas serupa dapat dicapai pada komponen individual. Ini akan dijelaskan nanti dalam dokumen ini.

@azure/msal-react menggunakan API Konteks React untuk membuat PublicClientApplication dan status autentikasi tersedia di seluruh pohon komponen Anda.

import { PublicClientApplication } from "@azure/msal-browser";
import { MsalProvider } from "@azure/msal-react";

const pca = new PublicClientApplication(config);

function App() {
    return (
        <MsalProvider instance={pca}>
            <YourAppComponents />
        </MsalProvider>
    );
}

Catatan umum tentang MsalProvider komponen:

  • Semua komponen yang membutuhkan akses ke status autentikasi atau kait/komponen yang diekspos oleh @azure/msal-react harus memiliki MsalProvider yang lebih tinggi di pohon komponen, oleh karena itu disarankan agar MsalProvider dirender sedekat mungkin dengan akar.
  • Aplikasi Anda tidak boleh merender lebih dari 1 MsalProvider komponen di halaman tertentu.
  • Kami tidak merekomendasikan inisialisasi PublicClientApplication di dalam komponen karena kemungkinan render ulang

Melindungi komponen Anda

Dalam react-aad-msal komponen dilindungi menggunakan AzureAD komponen atau withAuthentication HOC yang membungkus komponen Anda dengan AzureAD di bawah tenda. Komponen AzureAD hanya akan merender komponen turunan jika pengguna diautentikasi dan secara opsional memulai login jika tidak ada pengguna yang diautentikasi. Opsi yang digunakan untuk login (misalnya scope, apakah akan menggunakan pop-up atau pengalihan, dll.) ditetapkan sebelumnya, saat membuat prop authProvider.

import { MsalAuthProvider } from "react-aad-msal";

const authProvider = new MsalAuthProvider(config, authenticationParameters, options);

function App() {
    return (
        <AzureAD provider={authProvider} forceLogin={true}>
            <span>Only authenticated users can see me.</span>
        </AzureAD>
    );
}

@azure/msal-react, di sisi lain, memberi pengembang lebih banyak kontrol atas apa yang ingin mereka tampilkan kepada siapa.

  • Komponen AuthenticatedTemplate akan menampilkan konten anak jika pengguna terautentikasi
  • Komponen UnauthenticatedTemplate akan menampilkan elemen turunannya jika pengguna tidak terautentikasi
  • Komponen MsalAuthenticationTemplate akan secara otomatis memulai proses login jika pengguna belum diautentikasi, lalu merender komponen anak setelah pengguna diautentikasi.
import { PublicClientApplication, InteractionType } from "@azure/msal-browser";
import { MsalProvider, AuthenticatedTemplate, UnauthenticatedTemplate, MsalAuthenticationTemplate } from "@azure/msal-react";

const pca = new PublicClientApplication(config);

function App() {
    return (
        <MsalProvider instance={pca}>
            <AuthenticatedTemplate>
                <span>Only authenticated users can see me.</span>
            </AuthenticatedTemplate>
            <UnauthenticatedTemplate>
                <span>Only unauthenticated users can see me.</span>
            </UnauthenticatedTemplate>
            <MsalAuthenticationTemplate interactionType={InteractionType.Popup} authenticationRequest={request}>
                <span>Only authenticated users can see me. Unauthenticated users will get a popup asking them to login first.</span>
            </MsalAuthenticationTemplate>
        </MsalProvider>
    );
}

Selain itu, jika Anda lebih suka menggunakan pendekatan berbasis hook, @azure/msal-react menyediakan beberapa hook yang dapat Anda gunakan untuk mencapai hasil serupa. Ini hanyalah beberapa contoh dasar, dan Anda dapat mengacu pada MSAL React hooks untuk informasi lebih lanjut.

import { PublicClientApplication, InteractionType } from "@azure/msal-browser";
import { MsalProvider, useIsAuthenticated, useMsalAuthentication } from "@azure/msal-react";

const pca = new PublicClientApplication(config);

function App() {
    return (
        <MsalProvider instance={pca}>
            <ExampleComponent />
        </MsalProvider>
    );
}

function ExampleComponent() {
    const isAuthenticated = useIsAuthenticated();
    const { error } = useMsalAuthentication(InteractionType.Popup, request); // Will initiate a popup login if user is unauthenticated

    if (isAuthenticated) {
        return <span>Only authenticated users can see me.</span>
    } else if (error) {
        return <span>An error occurred during login!</span>
    } else {
        return <span>Only unauthenticated users can see me.</span>
    }
}

Memperoleh token akses

react-aad-msal mengekspos metode yang getAccessToken dapat Anda gunakan untuk mendapatkan token akses sebelum memanggil API.

import { MsalAuthProvider } from "react-aad-msal";

const authProvider = new MsalAuthProvider(config, authenticationParameters, options);
const accessToken = authProvider.getAccessToken();

Saat menggunakan @azure/msal-react dan @azure/msal-browser, Anda akan memanggil acquireTokenSilent pada instance PublicClientApplication.

Jika Anda perlu mendapatkan token akses di dalam komponen atau kait yang berada di bawah MsalProvider Anda dapat menggunakan useMsal kait untuk mendapatkan objek yang Anda butuhkan.

import { useState } from "react";
import { useMsal } from "@azure/msal-react";
import { InteractionRequiredAuthError } from "@azure/msal-browser";

function useAccessToken() {
    const { instance, accounts } = useMsal();
    const [accessToken, setAccessToken] = useState(null);

    if (accounts.length > 0) {
        const request = {
            scopes: ["User.Read"],
            account: accounts[0]
        };
        instance.acquireTokenSilent(request).then(response => {
            setAccessToken(response.accessToken);
        }).catch(error => {
            // acquireTokenSilent can fail for a number of reasons, fallback to interaction
            if (error instanceof InteractionRequiredAuthError) {
                instance.acquireTokenPopup(request).then(response => {
                    setAccessToken(response.accessToken);
                });
            }
        });
    }

    return accessToken;
}

Jika Anda perlu mendapatkan token akses di luar konteks MsalProvider , Anda dapat menggunakan PublicClientApplication instans secara langsung dan memanggil getAllAccounts() untuk mendapatkan objek akun.

Important

Hanya lakukan perolehan token senyap di luar konteks MsalProvider. Anda tidak boleh memanggil metode interaktif (pengalihan atau popup) di luar konteks MsalProvider.

Contoh di bawah ini menunjukkan inisialisasi PublicClientApplication untuk tujuan demonstrasi. PublicClientApplication hanya boleh diinisialisasi sekali per pemuatan halaman dan Anda harus menggunakan instans yang sama di sini yang Anda berikan ke MsalProvider.

import { PublicClientApplication } from "@azure/msal-browser";

const pca = new PublicClientApplication(config);
const accounts = pca.getAllAccounts();

async function getAccessToken() {
    if (accounts.length > 0) {
        const request = {
            scopes: ["User.Read"],
            account: accounts[0]
        }
        const accessToken = await pca.acquireTokenSilent(request).then((response) => {
            return response.accessToken;
        }).catch(error => {
            // Do not fallback to interaction when running outside the context of MsalProvider. Interaction should always be done inside context.
            console.log(error);
            return null;
        });

        return accessToken;
    }

    return null;
}

Memperoleh token ID

react-aad-msal getIdToken mengekspos fungsi untuk mendapatkan atau memperbarui idToken.

import { MsalAuthProvider } from "react-aad-msal";

const authProvider = new MsalAuthProvider(config, authenticationParameters, options);
const token = await authProvider.getIdToken();
const idToken = token.idToken.rawIdToken;

Anda mungkin juga terbiasa dengan pola meminta clientId sebagai satu-satunya scope untuk memperoleh idToken. Ini bukan lagi pola yang didukung di @azure/msal-browser.

Dalam @azure/msal-react dan @azure/msal-browser semua panggilan token akan mengembalikan token akses dan token id dan semua perpanjangan token akses juga akan memperbarui token id.

Jika Anda perlu mendapatkan token id di dalam komponen atau kait yang hidup di bawah MsalProvider Anda dapat menggunakan useMsal kait untuk mendapatkan objek yang Anda butuhkan.

import { useState } from "react";
import { useMsal } from "@azure/msal-react";

function useIdToken() {
    const { instance, accounts } = useMsal();
    const [idToken, setIdToken] = useState(null);

    if (accounts.length > 0) {
        const request = {
            scopes: ["openid"],
            account: accounts[0]
        };
        instance.acquireTokenSilent(request).then(response => {
            setIdToken(response.idToken);
        }).catch(error => {
            // acquireTokenSilent can fail for a number of reasons, fallback to interaction
            if (error instanceof InteractionRequiredAuthError) {
                instance.acquireTokenPopup(request).then(response => {
                    setIdToken(response.idToken);
                });
            }
        });
    }

    return idToken;
}

Jika Anda perlu mendapatkan token id di luar konteks MsalProvider , Anda dapat menggunakan PublicClientApplication instans secara langsung dan memanggil getAllAccounts() untuk mendapatkan objek akun.

Important

Hanya lakukan perolehan token senyap di luar konteks MsalProvider. Anda tidak boleh memanggil metode interaktif (pengalihan atau popup) di luar konteks MsalProvider.

Contoh di bawah ini menunjukkan inisialisasi PublicClientApplication untuk tujuan demonstrasi. PublicClientApplication hanya boleh diinisialisasi sekali per pemuatan halaman dan Anda harus menggunakan instans yang sama di sini yang Anda berikan ke MsalProvider.

import { PublicClientApplication } from "@azure/msal-browser";

const pca = new PublicClientApplication(config);
const accounts = pca.getAllAccounts();

async function getIdToken() {
    if (accounts.length > 0) {
        const request = {
            scopes: ["openid"],
            account: accounts[0]
        }
        const idToken = await pca.acquireTokenSilent(request).then((response) => {
            return response.idToken;
        }).catch (error => {
            // Do not fallback to interaction when running outside the context of MsalProvider. Interaction should always be done inside context.
            console.log(error);
            return null;
        });

        return idToken
    }

    return null;
}

Memperbarui integrasi penyimpanan redux / bereaksi terhadap peristiwa

react-aad-msal menyediakan integrasi siap pakai dengan store Redux dengan mengirimkan action saat peristiwa seperti login atau logout terjadi. @azure/msal-react tidak menyediakan fitur ini, namun, fungsionalitas serupa dapat dicapai menggunakan api peristiwa yang diekspos oleh @azure/msal-browser.

Anda dapat mendaftarkan panggilan balik peristiwa yang akan dipanggil setiap kali acara disiarkan (misalnya LOGIN_SUCCESS). Fungsi callback Anda dapat memeriksa event dan melakukan sesuatu terhadap payload. Jika Anda ingin tetap menggunakan redux store yang sudah ada, Anda dapat mendaftarkan callback event yang men-dispatch action ke store Anda.

import { PublicClientApplication, EventType } from "@azure/msal-browser";
import { store } from "your-redux-store-implementation";

const msalInstance = new PublicClientApplication(config);

const callbackId = msalInstance.addEventCallback((message: EventMessage) => {
    if (message.eventType === EventType.LOGIN_SUCCESS) {
        store.dispatchAction({type: "AAD_LOGIN_SUCCESS", payload: message.payload});
    }
});

Muatan data mungkin berbeda antara msal v1 dan @azure/msal-browser, jadi Anda mungkin perlu melakukan beberapa penyesuaian jika aplikasi Anda bergantung pada bidang tertentu atau struktur objek. Typedoc kami berisi daftar terbaru jenis peristiwa dan jenis payload dan Anda dapat menemukan pemetaan antara keduanya di dokumen peristiwa.

Baca juga