Kinerja di MSAL React

Cara mengonfigurasi @azure/msal-react untuk menggunakan fungsi navigasi router Anda untuk navigasi sisi klien

Secara bawaan, saat MSAL.js perlu menavigasi dari satu halaman di aplikasi Anda ke halaman lain, MSAL.js akan menetapkan ulang window.location, sehingga terjadi pengalihan bingkai penuh ke halaman lain dan aplikasi Anda dirender ulang. Jika Anda menggunakan router, hal ini mungkin tidak diinginkan karena banyak router menyediakan metode yang dapat Anda gunakan untuk melakukan navigasi "sisi klien" dan merender ulang hanya bagian halaman yang memang perlu dirender ulang.

Saat ini ada satu skenario di mana MSAL.js akan menavigasi dari satu halaman di aplikasi Anda ke halaman lainnya. Jika aplikasi Anda melakukan semua hal berikut, lanjutkan membaca:

  • Aplikasi Anda menggunakan alur pengalihan, alih-alih alur popup, untuk masuk
  • PublicClientApplication dikonfigurasi dengan auth.navigateToLoginRequestUrl: true (default)
  • Aplikasi Anda memiliki halaman yang dapat memanggil loginRedirect/acquireTokenRedirect dengan berbagi redirectUri yaitu Anda memanggil loginRedirect dari http://localhost/protected dengan redirectUri http://localhost

Jika aplikasi Anda melakukan semua hal di atas, Anda dapat mengambil alih metode yang digunakan Msal untuk menavigasi dengan membuat implementasi INavigationClient Anda sendiri dan memanggil setNavigationClient instans Anda PublicClientApplication sebelum merender MsalProvider.

Catatan: Kami menyarankan agar MsalProvider dirender di atas komponen Route Anda dan fungsi navigateInternal Anda mengembalikan false. Ketika navigateInternal mengembalikan false, token akan diproses segera setelah navigasi. Jika MsalProvider dirender ulang akibat navigasi, fungsi navigateInternal Anda harus mengembalikan true agar token diproses sebagai bagian dari perenderan ulang.

Contoh Implementasi

Setiap router memiliki metodenya sendiri untuk melakukan navigasi di sisi klien, dan bergantung pada cara metode tersebut disediakan, Anda mungkin perlu merombak aplikasi Anda agar mendukung fitur ini. Contoh di bawah ini akan menunjukkan cara menerapkan ini untuk react-router-dom. Anda dapat menemukan aplikasi sampel lengkap yang mengimplementasikan ini untuk react-router-dom, Next.js dan Gatsby.

Sampel ini disebutkan di atas memanfaatkan react-router-dom v6. Jika Anda ingin menggunakan react-router-dom v5 sebagai gantinya, silakan lihat: react-router-sample.

Implementasi INavigationClient

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

/**
 * Extending the default NavigationClient allows you to overwrite just navigateInternal while continuing to use the default navigateExternal function
 * If you would like to overwrite both you can implement INavigationClient directly instead
 */
class CustomNavigationClient extends NavigationClient{
    constructor(navigate) {
        super();
        this.navigate = navigate // Passed in from useNavigate hook provided by react-router-dom;
    }
    
    // This function will be called anytime msal needs to navigate from one page in your application to another
    async navigateInternal(url, options) {
        // url will be absolute, you will need to parse out the relative path to provide to the history API
        const relativePath = url.replace(window.location.origin, '');
        if (options.noHistory) {
            this.navigate(relativePath, {replace: true});
        } else {
            this.navigate(relativePath);
        }

        return false;
    }
}

Menyediakan NavigationClient kustom Anda ke @azure/msal-browser

import { MsalProvider } from "@azure/msal-react";
import { BrowserRouter as Router , Routes, Route, useNavigate } from "react-router-dom";

function App({ msalInstance }) {
    // It's important that the Router component is above the Example component because you'll need to use the useHistory hook before rendering MsalProvider
    return (
        <Router>
            <Example msalInstance={msalInstance}/>
        </Router>
    );
};

function Example({ msalInstance }) {
    const navigate = useNavigate();
    const navigationClient = new CustomNavigationClient(navigate);
    msalInstance.setNavigationClient(navigationClient);

    return (
        <MsalProvider instance={msalInstance}>
            <Routes>
                <Route path="/protected" element={<ProtectedRoute />} />
                <Route path="/" element={<Home />} />
            </Routes>
        </MsalProvider>
    )
}