Tutorial: Memasukkan pengguna dan memanggil Microsoft Graph API dari aplikasi satu halaman (single-page app atau SPA) React menggunakan alur kode autentikasi

Dalam tutorial ini, Anda membuat aplikasi satu halaman (SPA) React yang memasukkan pengguna dan memanggil Microsoft Graph menggunakan alur kode otorisasi dengan PKCE. SPA yang Anda buat menggunakan Pustaka Autentikasi Microsoft (MSAL) untuk React.

Dalam tutorial ini:

  • Buat proyek React dengan npm
  • Mendaftarkan aplikasi di portal Microsoft Azure
  • Menambahkan kode untuk mendukung upaya masuk dan keluar pengguna
  • Menambahkan kode untuk memanggil Microsoft Graph API
  • Menguji aplikasi

MSAL React mendukung alur kode otorisasi di browser alih-alih alur pemberian implisit. MSALReact TIDAK mendukung alur implisit.

Prasyarat

Cara kerja aplikasi tutorial

Diagram showing the authorization code flow in a single-page application

Aplikasi yang Anda buat dalam tutorial ini memungkinkan SPA React untuk membuat kueri Microsoft Graph API dengan memperoleh token keamanan dari platform identitas Microsoft. Ini menggunakan Pustaka Autentikasi Microsoft (MSAL) untuk React, wrapper pustaka MSAL.js v2. MSAL React memungkinkan aplikasi React 16+ mengautentikasi pengguna perusahaan dengan menggunakan Azure Active Directory (Azure AD), dan juga pengguna yang memiliki akun Microsoft dan identitas sosial seperti Facebook, Google, dan LinkedIn. Pustaka juga memungkinkan aplikasi mendapatkan akses ke layanan awan Microsoft dan Microsoft Graph.

Dalam skenario ini, setelah pengguna masuk, token akses diminta dan ditambahkan ke permintaan HTTP di header otorisasi. Akuisisi dan pembaruan token ditangani oleh Microsoft Authentication Library untuk React (MSAL.React).

Pustaka

Tutorial ini menggunakan pustaka berikut:

Pustaka Deskripsi
MSAL React Pustaka Autentikasi Microsoft untuk JavaScript React Wrapper
Browser MSAL Pustaka Autentikasi Microsoft untuk paket browser JavaScript v2

Dapatkan sampel kode yang telah selesai

Lebih suka mengunduh proyek sampel tutorial yang sudah selesai ini? Untuk menjalankan proyek dengan menggunakan server web lokal, seperti Node.js, buat klon ms-identity-javascript-react-spa:

git clone https://github.com/Azure-Samples/ms-identity-javascript-react-spa

Kemudian, untuk mengonfigurasi sampel kode sebelum Anda menjalankannya, lewati ke langkah konfigurasi.

Untuk melanjutkan tutorial dan membuat aplikasi sendiri, lanjutkan ke bagian berikutnya, Prasyarat.

Membuat proyek

Setelah Anda memasang Node.js, buka jendela terminal kemudian jalankan perintah berikut:

npx create-react-app msal-react-tutorial # Create a new React app
cd msal-react-tutorial # Change to the app directory
npm install @azure/msal-browser @azure/msal-react # Install the MSAL packages
npm install react-bootstrap bootstrap # Install Bootstrap for styling

Anda sekarang telah membootstrap proyek React kecil menggunakan Create React App. Ini akan menjadi titik awal yang akan dibangun sisa tutorial ini. Jika Anda ingin melihat perubahan pada aplikasi saat Anda bekerja melalui tutorial ini, Anda dapat menjalankan perintah berikut:

npm start

Jendela browser harus dibuka ke aplikasi Anda secara otomatis. Jika tidak, buka browser Anda dan navigasikan ke http://localhost:3000. Setiap kali Anda menyimpan file dengan kode yang diperbarui, halaman akan dimuat ulang untuk mencerminkan perubahan.

Mendaftarkan aplikasi Anda

Ikuti langkah-langkah dalam Aplikasi satu halaman: Pendaftaran aplikasi untuk membuat pendaftaran aplikasi untuk SPA Anda menggunakan portal Microsoft Azure.

Di langkah Alihkan URI: MSAL.js 2.0 dengan alur kode otorisasi, masuk ke , lokasi default tempat creat-react-app akan melayani aplikasi ini.

Mengonfigurasi JavaScript SPA

  1. Buat file bernama authConfig.js dalam folder src guna memuat parameter konfigurasi untuk autentikasi, lalu tambahkan kode berikut:

    export const msalConfig = {
      auth: {
        clientId: "Enter_the_Application_Id_Here",
        authority: "Enter_the_Cloud_Instance_Id_Here/Enter_the_Tenant_Info_Here", // This is a URL (e.g. https://login.microsoftonline.com/{your tenant ID})
        redirectUri: "Enter_the_Redirect_Uri_Here",
      },
      cache: {
        cacheLocation: "sessionStorage", // This configures where your cache will be stored
        storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
      }
    };
    
    // Add scopes here for ID token to be used at Microsoft identity platform endpoints.
    export const loginRequest = {
     scopes: ["User.Read"]
    };
    
    // Add the endpoints here for Microsoft Graph API services you'd like to use.
    export const graphConfig = {
        graphMeEndpoint: "Enter_the_Graph_Endpoint_Here/v1.0/me"
    };
    
  2. Ubah nilai di bagian msalConfig seperti yang dijelaskan di sini:

    Nama nilai Tentang
    Enter_the_Application_Id_Here ID Aplikasi (klien) dari aplikasi yang Anda daftarkan.
    Enter_the_Cloud_Instance_Id_Here Instans cloud Azure tempat aplikasi Anda terdaftar. Untuk cloud Azure utama (atau global),masukkan . Untuk cloud nasional (misalnya, Cina), Anda dapat menemukan nilai yang sesuai di Cloud nasional.
    Enter_the_Tenant_Info_Here Atur ke salah satu opsi berikut: Jika aplikasi Anda mendukung akun di direktori organisasi ini, ganti nilai ini dengan ID direktori (penyewa) atau nama penyewa (misalnya, contoso.microsoft.com). Jika aplikasi Anda mendukung akun di direktori organisasi apa pun, ganti nilai ini dengan organisasi. Jika aplikasi Anda mendukung akun di direktori organisasi dan akun Microsoft pribadi apa pun, ganti nilai ini dengan umum. Untuk membatasi dukungan pada akun Microsoft pribadi saja, ganti nilai ini dengan konsumen.
    Enter_the_Redirect_Uri_Here Ganti dengan http://localhost:3000.
    Enter_the_Graph_Endpoint_Here Instans Microsoft Graph API yang harus berkomunikasi dengan aplikasi. Untuk titik akhir Microsoft Graph API global, ganti kedua instans string ini dengan . Untuk titik akhir dalam penyebaran cloud nasional, lihat Penyebaran cloud nasional dalam dokumentasi Microsoft Graph.

    Untuk mengetahui informasi selengkapnya tentang opsi yang dapat dikonfigurasi yang tersedia, lihat Menginisialisasi aplikasi klien.

  3. Buka berkas src/index.js dan tambahkan impor berikut:

    import "bootstrap/dist/css/bootstrap.min.css";
    import { PublicClientApplication } from "@azure/msal-browser";
    import { MsalProvider } from "@azure/msal-react";
    import { msalConfig } from "./authConfig";
    
  4. Di bawah impor dalam src/index.js buat instans menggunakan konfigurasi dari langkah 1.

    const msalInstance = new PublicClientApplication(msalConfig);
    
  5. Temukan <App /> komponen dalam <App /> dan bungkus dengan komponenMsalProvider. Fungsi render Anda akan terlihat seperti ini:

    ReactDOM.render(
        <React.StrictMode>
            <MsalProvider instance={msalInstance}>
                <App />
            </MsalProvider>
        </React.StrictMode>,
        document.getElementById("root")
    );
    

Memasukkan pengguna

Buat folder di src yang disebut komponen dan buat file di dalam folder ini yang bernama SignInButton.jsx. Tambahkan kode dari bagian berikut untuk memanggil info masuk menggunakan jendela popup atau dari pengalihan bingkai penuh:

Masuk menggunakan pop-up

Tambahkan kode berikut ke src/components/SignInButton.jsx untuk membuat komponen tombol yang akan memanggil masuk popup saat dipilih:

import React from "react";
import { useMsal } from "@azure/msal-react";
import { loginRequest } from "../authConfig";
import Button from "react-bootstrap/Button";

function handleLogin(instance) {
    instance.loginPopup(loginRequest).catch(e => {
        console.error(e);
    });
}

/**
 * Renders a button which, when selected, will open a popup for login
 */
export const SignInButton = () => {
    const { instance } = useMsal();

    return (
        <Button variant="secondary" className="ml-auto" onClick={() => handleLogin(instance)}>Sign in using Popup</Button>
    );
}

Masuk menggunakan pengalihan

Tambahkan kode berikut ke src/components/SignInButton.jsx untuk membuat komponen tombol yang akan memanggil login pengalihan saat dipilih:

import React from "react";
import { useMsal } from "@azure/msal-react";
import { loginRequest } from "../authConfig";
import Button from "react-bootstrap/Button";

function handleLogin(instance) {
    instance.loginRedirect(loginRequest).catch(e => {
        console.error(e);
    });
}

/**
 * Renders a button which, when selected, will redirect the page to the login prompt
 */
export const SignInButton = () => {
    const { instance } = useMsal();

    return (
        <Button variant="secondary" className="ml-auto" onClick={() => handleLogin(instance)}>Sign in using Redirect</Button>
    );
}

Menambahkan tombol masuk

  1. Buat file lain di folder komponen bernama PageLayout.jsx dan tambahkan kode berikut untuk membuat komponen navbar yang akan berisi tombol masuk yang baru saja Anda buat:

    import React from "react";
    import Navbar from "react-bootstrap/Navbar";
    import { useIsAuthenticated } from "@azure/msal-react";
    import { SignInButton } from "./SignInButton";
    
    /**
     * Renders the navbar component with a sign-in button if a user is not authenticated
     */
    export const PageLayout = (props) => {
        const isAuthenticated = useIsAuthenticated();
    
        return (
            <>
                <Navbar bg="primary" variant="dark">
                    <a className="navbar-brand" href="/">MSAL React Tutorial</a>
                    { isAuthenticated ? <span>Signed In</span> : <SignInButton /> }
                </Navbar>
                <h5><center>Welcome to the Microsoft Authentication Library For React Tutorial</center></h5>
                <br />
                <br />
                {props.children}
            </>
        );
    };
    
  2. Sekarang buka src/App.js dan tambahkan ganti konten yang sudah ada dengan kode berikut:

    import React from "react";
    import { PageLayout } from "./components/PageLayout";
    
    function App() {
      return (
          <PageLayout>
              <p>This is the main app content!</p>
          </PageLayout>
      );
    }
    
    export default App;
    

Aplikasi Anda sekarang memiliki tombol masuk yang hanya ditampilkan untuk pengguna yang tidak diautentikasi!

Saat pengguna memilih tombol Masuk menggunakan Popup atau Masuk menggunakan tombol Alihkan untuk pertama kalinya, penangan memanggil (atau loginRedirect) untuk memasukkan pengguna. Metode loginPopup membuka jendela pop-up dengan loginPopup untuk meminta dan memvalidasi info masuk pengguna. Setelah berhasil masuk, msal.js memulai alur kode otorisasi.

Pada titik ini, kode otorisasi yang dilindungi PKCE dikirim ke titik akhir token yang dilindungi CORS dan ditukar dengan token. Token ID, token akses, dan token refresh diterima oleh aplikasi Anda dan diproses oleh msal.js, dan informasi yang terkandung dalam token disimpan di-cache.

Mengeluarkan pengguna

Dalam src/components buat file bernama SignOutButton.jsx. Tambahkan kode dari bagian berikut untuk memanggil info keluar menggunakan jendela popup atau pengalihan bingkai penuh:

Keluar menggunakan popup

Tambahkan kode berikut ke src/components/SignOutButton.jsx untuk membuat komponen tombol yang akan memanggil keluar popup saat dipilih:

import React from "react";
import { useMsal } from "@azure/msal-react";
import Button from "react-bootstrap/Button";

function handleLogout(instance) {
    instance.logoutPopup().catch(e => {
        console.error(e);
    });
}

/**
 * Renders a button which, when selected, will open a popup for logout
 */
export const SignOutButton = () => {
    const { instance } = useMsal();

    return (
        <Button variant="secondary" className="ml-auto" onClick={() => handleLogout(instance)}>Sign out using Popup</Button>
    );
}

Keluar menggunakan pengalihan

Tambahkan kode berikut ke src/components/SignInButton.jsx untuk membuat komponen tombol yang akan memanggil login popup saat dipilih:

import React from "react";
import { useMsal } from "@azure/msal-react";
import Button from "react-bootstrap/Button";

function handleLogout(instance) {
    instance.logoutRedirect().catch(e => {
        console.error(e);
    });
}

/**
 * Renders a button which, when selected, will redirect the page to the logout prompt
 */
export const SignOutButton = () => {
    const { instance } = useMsal();

    return (
        <Button variant="secondary" className="ml-auto" onClick={() => handleLogout(instance)}>Sign out using Redirect</Button>
    );
}

Menambahkan tombol keluar

Perbarui komponen PageLayout Anda dalam PageLayout untuk merender SignOutButtonkomponen baru bagi pengguna terautentikasi. Kode Anda akan terlihat seperti ini:

import React from "react";
import Navbar from "react-bootstrap/Navbar";
import { useIsAuthenticated } from "@azure/msal-react";
import { SignInButton } from "./SignInButton";
import { SignOutButton } from "./SignOutButton";

/**
 * Renders the navbar component with a sign-in button if a user is not authenticated
 */
export const PageLayout = (props) => {
    const isAuthenticated = useIsAuthenticated();

    return (
        <>
            <Navbar bg="primary" variant="dark">
                <a className="navbar-brand" href="/">MSAL React Tutorial</a>
                { isAuthenticated ? <SignOutButton /> : <SignInButton /> }
            </Navbar>
            <h5><center>Welcome to the Microsoft Authentication Library For React Tutorial</center></h5>
            <br />
            <br />
            {props.children}
        </>
    );
};

Komponen render bersyarat

Untuk merender komponen tertentu hanya untuk pengguna yang diautentikasi atau tidak diautentikasi gunakan AuthenticateTemplate dan/atau UnauthenticatedTemplate seperti yang ditunjukkan di bawah ini.

  1. Tambahkan impor berikut ke src/App.js:

    import { AuthenticatedTemplate, UnauthenticatedTemplate } from "@azure/msal-react";
    
  2. Untuk merender komponen tertentu hanya untuk pengguna terautentikasi perbarui fungsi App Anda di App dengan kode berikut:

    function App() {
        return (
            <PageLayout>
                <AuthenticatedTemplate>
                    <p>You are signed in!</p>
                </AuthenticatedTemplate>
            </PageLayout>
        );
    }
    
  3. Untuk merender komponen tertentu hanya untuk pengguna yang tidak terautentikasi, seperti saran untuk masuk, perbarui fungsi App Anda di App dengan kode berikut:

    function App() {
        return (
            <PageLayout>
                <AuthenticatedTemplate>
                    <p>You are signed in!</p>
                </AuthenticatedTemplate>
                <UnauthenticatedTemplate>
                    <p>You are not signed in! Please sign in.</p>
                </UnauthenticatedTemplate>
            </PageLayout>
        );
    }
    

Memperoleh token

  1. Sebelum memanggil API, seperti Microsoft Graph, Anda harus memperoleh token akses. Tambahkan komponen baru ke src/App.js yang dipanggil dengan kode berikut:

    function ProfileContent() {
        const { instance, accounts, inProgress } = useMsal();
        const [accessToken, setAccessToken] = useState(null);
    
        const name = accounts[0] && accounts[0].name;
    
        function RequestAccessToken() {
            const request = {
                ...loginRequest,
                account: accounts[0]
            };
    
            // Silently acquires an access token which is then attached to a request for Microsoft Graph data
            instance.acquireTokenSilent(request).then((response) => {
                setAccessToken(response.accessToken);
            }).catch((e) => {
                instance.acquireTokenPopup(request).then((response) => {
                    setAccessToken(response.accessToken);
                });
            });
        }
    
        return (
            <>
                <h5 className="card-title">Welcome {name}</h5>
                {accessToken ? 
                    <p>Access Token Acquired!</p>
                    :
                    <Button variant="secondary" onClick={RequestAccessToken}>Request Access Token</Button>
                }
            </>
        );
    };
    
  2. Perbarui impor Anda dalam src/App.js untuk mencocokkan dengan yang berikut:

    import React, { useState } from "react";
    import { PageLayout } from "./components/PageLayout";
    import { AuthenticatedTemplate, UnauthenticatedTemplate, useMsal } from "@azure/msal-react";
    import { loginRequest } from "./authConfig";
    import Button from "react-bootstrap/Button";
    
  3. Terakhir, tambahkan komponen ProfileContent baru Anda sebagai anak dari AuthenticatedTemplate komponen App Anda pada ProfileContent. Komponen App Anda akan terlihat seperti ini:

    function App() {
      return (
          <PageLayout>
              <AuthenticatedTemplate>
                  <ProfileContent />
              </AuthenticatedTemplate>
              <UnauthenticatedTemplate>
                  <p>You are not signed in! Please sign in.</p>
              </UnauthenticatedTemplate>
          </PageLayout>
      );
    }
    

Kode di atas akan merender tombol untuk pengguna yang masuk, memungkinkan mereka meminta token akses untuk Microsoft Graph ketika tombol dipilih.

Setelah pengguna masuk, aplikasi Anda tidak akan meminta pengguna untuk mengautentikasi ulang setiap kali mereka perlu mengakses sumber daya yang dilindungi (yakni, meminta token). Untuk mencegah permintaan reautentikasi tersebut, panggilan acquireTokenSilent yang pertama-tama akan mencari token akses yang di-cache dan tidak kedaluwarsa kemudian, jika diperlukan, gunakan token refresh untuk mendapatkan token akses baru. Namun, ada beberapa situasi di mana Anda mungkin harus memaksa pengguna untuk berinteraksi dengan platform identitas Microsoft. Contohnya:

  • Pengguna perlu memasukkan kembali info masuk mereka karena kata sandi telah kedaluwarsa.
  • Token refresh telah kedaluwarsa...
  • Aplikasi meminta akses ke sumber daya dan Anda memerlukan persetujuan pengguna.
  • Autentikasi dua faktor diperlukan.

Panggilan acquireTokenPopup membuka jendela pop-up (atau acquireTokenRedirect mengalihkan pengguna ke platform identitas Microsoft). Di jendela tersebut, pengguna perlu berinteraksi dengan mengonfirmasi info masuk mereka, memberikan persetujuan ke sumber daya yang diperlukan, atau menyelesaikan autentikasi dua faktor.

Catatan

Jika Anda menggunakan Internet Explorer, kami menyarankan agar Anda menggunakan metode loginRedirect dan acquireTokenRedirect karena loginRedirect dengan jendela Internet Explorer dan jendela pop-up.

Menghubungi Microsoft Graph API

  1. Buat file bernama graph.js di folder src dan tambahkan kode berikut untuk melakukan panggilan REST ke Microsoft Graph API:

    import { graphConfig } from "./authConfig";
    
    /**
     * Attaches a given access token to a Microsoft Graph API call. Returns information about the user
     */
    export async function callMsGraph(accessToken) {
        const headers = new Headers();
        const bearer = `Bearer ${accessToken}`;
    
        headers.append("Authorization", bearer);
    
        const options = {
            method: "GET",
            headers: headers
        };
    
        return fetch(graphConfig.graphMeEndpoint, options)
            .then(response => response.json())
            .catch(error => console.log(error));
    }
    
  2. Selanjutnya buat file bernama ProfileData.jsx di src/components dan tambahkan kode berikut:

    import React from "react";
    
    /**
     * Renders information about the user obtained from Microsoft Graph
     */
    export const ProfileData = (props) => {
        return (
            <div id="profile-div">
                <p><strong>First Name: </strong> {props.graphData.givenName}</p>
                <p><strong>Last Name: </strong> {props.graphData.surname}</p>
                <p><strong>Email: </strong> {props.graphData.userPrincipalName}</p>
                <p><strong>Id: </strong> {props.graphData.id}</p>
            </div>
        );
    };
    
  3. Selanjutnya, buka src/App.js dan tambahkan ke impor:

    import { ProfileData } from "./components/ProfileData";
    import { callMsGraph } from "./graph";
    
  4. Terakhir, perbarui komponen ProfileContent Anda di ProfileContent untuk memanggil Microsoft Graph dan menampilkan data profil setelah memperoleh token. Komponen ProfileContent Anda akan terlihat seperti ini:

    function ProfileContent() {
        const { instance, accounts } = useMsal();
        const [graphData, setGraphData] = useState(null);
    
        const name = accounts[0] && accounts[0].name;
    
        function RequestProfileData() {
            const request = {
                ...loginRequest,
                account: accounts[0]
            };
    
            // Silently acquires an access token which is then attached to a request for Microsoft Graph data
            instance.acquireTokenSilent(request).then((response) => {
                callMsGraph(response.accessToken).then(response => setGraphData(response));
            }).catch((e) => {
                instance.acquireTokenPopup(request).then((response) => {
                    callMsGraph(response.accessToken).then(response => setGraphData(response));
                });
            });
        }
    
        return (
            <>
                <h5 className="card-title">Welcome {name}</h5>
                {graphData ? 
                    <ProfileData graphData={graphData} />
                    :
                    <Button variant="secondary" onClick={RequestProfileData}>Request Profile Information</Button>
                }
            </>
        );
    };
    

Pada perubahan yang dibuat di atas, metode callMSGraph() digunakan untuk membuat permintaan GET HTTP terhadap sumber daya yang dilindungi yang memerlukan token akses. Kemudian, permintaan mengembalikan konten ke penelepon. Metode ini akan menambahkan token yang diperoleh di header Otorisasi HTTP. Dalam aplikasi contoh yang dibuat dalam tutorial ini, sumber daya yang dilindungi adalah titik akhir me Microsoft Graph API, yang menampilkan informasi profil pengguna masuk.

Menguji aplikasi Anda

Anda telah menyelesaikan pembuatan aplikasi dan sekarang siap meluncurkan web server dan menguji fungsi aplikasi.

  1. Mulai aplikasi dengan menjalankan perintah berikut dari dalam akar folder proyek Anda:

    npm start
    
  2. Jendela browser harus dibuka ke aplikasi Anda secara otomatis. Jika tidak, buka browser Anda dan navigasi ke http://localhost:3000. Anda akan melihat halaman yang tampak seperti berikut ini.

    Web browser displaying sign-in dialog

  3. Pilih tombol masuk untuk masuk.

Saat pertama kali masuk ke aplikasi, Anda diminta untuk memberikannya akses ke profil Anda dan membiarkan Anda masuk:

Content dialog displayed in web browser

Jika Anda menyetujui izin yang diminta, aplikasi web akan menampilkan nama pengguna Anda, yang menandakan bahwa proses masuk berhasil:

Results of a successful sign-in in the web browser

Memanggil Graph API

Setelah masuk, pilih Lihat Profil untuk melihat informasi profil pengguna yang ditampilkan dalam respons dari panggilan ke Microsoft Graph API:

Profile information from Microsoft Graph displayed in the browser

Informasi selengkapnya tentang cakupan dan izin yang didelegasikan

Microsoft Graph API memerlukan cakupan user.read untuk membaca profil pengguna. Secara default, cakupan ini otomatis ditambahkan di setiap aplikasi yang terdaftar di portal Microsoft Azure. API lain untuk Microsoft Graph, serta API kustom untuk server ujung belakang, mungkin mewajibkan cakupan tambahan. Misalnya, Microsoft Graph API memerlukan cakupan Mail.Read untuk mencantumkan email pengguna.

Saat Anda menambahkan cakupan, pengguna Anda mungkin diminta untuk memberikan persetujuan tambahan untuk cakupan yang ditambahkan.

Bantuan dan dukungan

Jika Anda memerlukan bantuan, ingin melaporkan masalah, atau ingin mempelajari opsi dukungan, lihat Bantuan dan dukungan bagi pengembang.

Langkah berikutnya

Jika Anda ingin mendalami pengembangan aplikasi satu halaman JavaScript di platform identitas Microsoft, lihat rangkaian skenario beberapa bagian kami: