Руководство. Вход пользователей и вызов API Microsoft Graph из одностраничного приложения JavaScript (SPA) с помощью потока кода проверки подлинности
В этом руководстве показано, как создать одностраничное приложение (SPA) JavaScript, которое поддерживает вход пользователей и вызовы Microsoft Graph с использованием потока кода авторизации с PKCE. Создаваемое одностраничное приложение использует библиотеку проверки подлинности Майкрософт (MSAL) для JavaScript версии 2.0.
В этом руководстве рассматриваются следующие темы:
- Выполнение потока кода авторизации OAuth 2.0 с PKCE
- Вход в личные, рабочие и учебные учетные записи Майкрософт
- Получение маркера доступа
- Вызов API Microsoft Graph или собственного API, которые требуют маркеры доступа, полученные от платформы удостоверений Майкрософт
MSAL.js 2.0 — это расширенная версия MSAL.js 1.0, поддерживающая поток кода авторизации в браузере вместо потока неявного предоставления разрешения. MSAL.js 2.0 НЕ поддерживает неявный поток.
Необходимые компоненты
- Node.js для запуска локального веб-сервера
- Visual Studio Code или любой другой редактор кода.
Принципы работы приложения из учебника
Созданное в этом руководстве приложение позволяет SPA JavaScript запрашивать API Microsoft Graph путем получения маркеров безопасности из платформа удостоверений Майкрософт. В этом сценарии после входа в систему маркер доступа запрашивается и добавляется в HTTP-запросы в заголовок авторизации. Получение маркера и его обновление выполняет библиотека проверки подлинности Майкрософт (MSAL.js).
В этом руководстве используется MSAL.js пакет браузера Microsoft Authentication Library для JavaScript версии 2.0.
Получение готового примера кода
Вместо этого можно скачать пример проекта этого руководства, клонируя репозиторий ms-identity-javascript-v2 .
git clone https://github.com/Azure-Samples/ms-identity-javascript-v2.git
Чтобы запустить скачанный проект в локальной среде разработки, создайте сервер localhost для приложения, как описано в шаге 1 статьи в разделе Создание проекта. После этого вы можете настроить пример кода, пропустив шаг настройки.
Чтобы продолжить работу с руководством и самостоятельно создать приложение, перейдите к разделу Создание проекта.
Создание проекта
После установки Node.js создайте папку для размещения приложения, напримерmsal-spa-tutorial
.
Теперь реализуйте небольшой веб-сервер Express для обслуживания файла index.html.
Сначала перейдите в окне терминала в каталог проекта, а затем выполните следующие команды
npm
:npm init -y npm install @azure/msal-browser npm install express npm install morgan npm install yargs
Далее создайте файл с именем server.js и добавьте в него следующий код:
const express = require('express'); const morgan = require('morgan'); const path = require('path'); const DEFAULT_PORT = process.env.PORT || 3000; // initialize express. const app = express(); // Initialize variables. let port = DEFAULT_PORT; // Configure morgan module to log all requests. app.use(morgan('dev')); // Setup app folders. app.use(express.static('app')); // Set up a route for index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname + '/index.html')); }); // Start the server. app.listen(port); console.log(`Listening on port ${port}...`);
Создание пользовательского интерфейса одностраничного приложения
Создайте в каталоге проекта папку app, а в ней — файл index.html для одностраничного приложения JavaScript. Этот файл используется для реализации пользовательского интерфейса, созданного на платформе Bootstrap 4, и импорта файлов скриптов для настройки, проверки подлинности и вызовов API.
В файле index.html добавьте следующий код:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"> <title>Microsoft identity platform</title> <link rel="SHORTCUT ICON" href="./favicon.svg" type="image/x-icon"> <!-- msal.min.js can be used in the place of msal.js; included msal.js to make debug easy --> <script src="https://alcdn.msauth.net/browser/2.30.0/js/msal-browser.js" integrity="sha384-o4ufwq3oKqc7IoCcR08YtZXmgOljhTggRwxP2CLbSqeXGtitAxwYaUln/05nJjit" crossorigin="anonymous"></script> <!-- adding Bootstrap 4 for UI components --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <link rel="SHORTCUT ICON" href="https://c.s-microsoft.com/favicon.ico?v2" type="image/x-icon"> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark bg-primary"> <a class="navbar-brand" href="/">Microsoft identity platform</a> <div class="btn-group ml-auto dropleft"> <button type="button" id="SignIn" class="btn btn-secondary" onclick="signIn()"> Sign In </button> </div> </nav> <br> <h5 class="card-header text-center">Vanilla JavaScript SPA calling MS Graph API with MSAL.js</h5> <br> <div class="row" style="margin:auto"> <div id="card-div" class="col-md-3" style="display:none"> <div class="card text-center"> <div class="card-body"> <h5 class="card-title" id="WelcomeMessage">Please sign-in to see your profile and read your mails</h5> <div id="profile-div"></div> <br> <br> <button class="btn btn-primary" id="seeProfile" onclick="seeProfile()">See Profile</button> <br> <br> <button class="btn btn-primary" id="readMail" onclick="readMail()">Read Mails</button> </div> </div> </div> <br> <br> <div class="col-md-4"> <div class="list-group" id="list-tab" role="tablist"> </div> </div> <div class="col-md-5"> <div class="tab-content" id="nav-tabContent"> </div> </div> </div> <br> <br> <!-- importing bootstrap.js and supporting js libraries --> <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> <!-- importing app scripts (load order is important) --> <script type="text/javascript" src="./authConfig.js"></script> <script type="text/javascript" src="./graphConfig.js"></script> <script type="text/javascript" src="./ui.js"></script> <!-- <script type="text/javascript" src="./authRedirect.js"></script> --> <!-- uncomment the above line and comment the line below if you would like to use the redirect flow --> <script type="text/javascript" src="./authPopup.js"></script> <script type="text/javascript" src="./graph.js"></script> </body> </html>
Затем в папке app создайте файл с именем ui.js и добавьте следующий код. Этот файл будет обращаться к элементам модели DOM и обновлять их.
// Select DOM elements to work with const welcomeDiv = document.getElementById("WelcomeMessage"); const signInButton = document.getElementById("SignIn"); const cardDiv = document.getElementById("card-div"); const mailButton = document.getElementById("readMail"); const profileButton = document.getElementById("seeProfile"); const profileDiv = document.getElementById("profile-div"); function showWelcomeMessage(username) { // Reconfiguring DOM elements cardDiv.style.display = 'initial'; welcomeDiv.innerHTML = `Welcome ${username}`; signInButton.setAttribute("onclick", "signOut();"); signInButton.setAttribute('class', "btn btn-success") signInButton.innerHTML = "Sign Out"; } function updateUI(data, endpoint) { console.log('Graph API responded at: ' + new Date().toString()); if (endpoint === graphConfig.graphMeEndpoint) { profileDiv.innerHTML = '' const title = document.createElement('p'); title.innerHTML = "<strong>Title: </strong>" + data.jobTitle; const email = document.createElement('p'); email.innerHTML = "<strong>Mail: </strong>" + data.mail; const phone = document.createElement('p'); phone.innerHTML = "<strong>Phone: </strong>" + data.businessPhones[0]; const address = document.createElement('p'); address.innerHTML = "<strong>Location: </strong>" + data.officeLocation; profileDiv.appendChild(title); profileDiv.appendChild(email); profileDiv.appendChild(phone); profileDiv.appendChild(address); } else if (endpoint === graphConfig.graphMailEndpoint) { if (!data.value) { alert("You do not have a mailbox!") } else if (data.value.length < 1) { alert("Your mailbox is empty!") } else { const tabContent = document.getElementById("nav-tabContent"); const tabList = document.getElementById("list-tab"); tabList.innerHTML = ''; // clear tabList at each readMail call data.value.map((d, i) => { // Keeping it simple if (i < 10) { const listItem = document.createElement("a"); listItem.setAttribute("class", "list-group-item list-group-item-action") listItem.setAttribute("id", "list" + i + "list") listItem.setAttribute("data-toggle", "list") listItem.setAttribute("href", "#list" + i) listItem.setAttribute("role", "tab") listItem.setAttribute("aria-controls", i) listItem.innerHTML = d.subject; tabList.appendChild(listItem) const contentItem = document.createElement("div"); contentItem.setAttribute("class", "tab-pane fade") contentItem.setAttribute("id", "list" + i) contentItem.setAttribute("role", "tabpanel") contentItem.setAttribute("aria-labelledby", "list" + i + "list") contentItem.innerHTML = "<strong> from: " + d.from.emailAddress.address + "</strong><br><br>" + d.bodyPreview + "..."; tabContent.appendChild(contentItem); } }); } } }
Регистрация приложения
Выполните действия, описанные в одностраничных приложениях: регистрация приложений для создания регистрации приложения для SPA.
На шаге URI перенаправления: MSAL.js 2.0 с потоком кода авторизации введите http://localhost:3000
— расположение по умолчанию, в котором выполняется приложение этого учебника.
Если вы хотите использовать другой порт, введите http://localhost:<port>
, где <port>
— предпочтительный номер TCP-порта. Если указан номер порта, отличный от 3000
, обновите также server.js, указав предпочтительный номер порта.
Настройка одностраничного приложения JavaScript
В папке app создайте файл с именем authConfig.js, который будет содержать параметры конфигурации для проверки подлинности, а затем добавьте в него следующий код:
/**
* Configuration object to be passed to MSAL instance on creation.
* For a full list of MSAL.js configuration parameters, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md
*/
const msalConfig = {
auth: {
// 'Application (client) ID' of app registration in Azure portal - this value is a GUID
clientId: "Enter_the_Application_Id_Here",
// Full directory URL, in the form of https://login.microsoftonline.com/<tenant-id>
authority: "Enter_the_Cloud_Instance_Id_HereEnter_the_Tenant_Info_Here",
// Full redirect URL, in form of http://localhost:3000
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
},
system: {
loggerOptions: {
loggerCallback: (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case msal.LogLevel.Error:
console.error(message);
return;
case msal.LogLevel.Info:
console.info(message);
return;
case msal.LogLevel.Verbose:
console.debug(message);
return;
case msal.LogLevel.Warning:
console.warn(message);
return;
}
}
}
}
};
/**
* Scopes you add here will be prompted for user consent during sign-in.
* By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
* For more information about OIDC scopes, visit:
* https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
*/
const loginRequest = {
scopes: ["User.Read"]
};
/**
* Add here the scopes to request when obtaining an access token for MS Graph API. For more information, see:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/resources-and-scopes.md
*/
const tokenRequest = {
scopes: ["User.Read", "Mail.Read"],
forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token
};
В той же папке app создайте файл с именем graphConfig.js. Добавьте следующий код, чтобы предоставить приложению параметры конфигурации для вызова API Microsoft Graph:
// Add here the endpoints for MS Graph API services you would like to use.
const graphConfig = {
graphMeEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me",
graphMailEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me/messages"
};
Измените значения в разделе graphConfig
, как описано далее.
Enter_the_Graph_Endpoint_Here
экземпляр API Microsoft Graph, с которым должно взаимодействовать приложение.- Для глобальной конечной точки API Microsoft Graph замените оба экземпляра этой строки на
https://graph.microsoft.com
. - Дополнительные сведения о конечных точках в национальных облачных развертываниях см. в статье Национальные облачные развертывания в документации по Microsoft Graph.
- Для глобальной конечной точки API Microsoft Graph замените оба экземпляра этой строки на
Если вы используете глобальную конечную точку, значения graphMeEndpoint
и graphMailEndpoint
в файле authConfig.js должно выглядеть примерно так:
graphMeEndpoint: "https://graph.microsoft.com/v1.0/me",
graphMailEndpoint: "https://graph.microsoft.com/v1.0/me/messages"
Использование библиотеки проверки подлинности Майкрософт (MSAL) для входа пользователя
Всплывающее окно
В папке app создайте файл с именем authPopup.js и добавьте следующий код для проверки подлинности и получения маркера для всплывающего окна входа:
// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication(msalConfig);
let username = "";
function selectAccount() {
/**
* See here for more info on account retrieval:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
*/
const currentAccounts = myMSALObj.getAllAccounts();
if (currentAccounts.length === 0) {
return;
} else if (currentAccounts.length > 1) {
// Add choose account code here
console.warn("Multiple accounts detected.");
} else if (currentAccounts.length === 1) {
username = currentAccounts[0].username;
showWelcomeMessage(username);
}
}
function handleResponse(response) {
/**
* To see the full list of response object properties, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#response
*/
if (response !== null) {
username = response.account.username;
showWelcomeMessage(username);
} else {
selectAccount();
}
}
function signIn() {
/**
* You can pass a custom request object below. This will override the initial configuration. For more information, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
*/
myMSALObj.loginPopup(loginRequest)
.then(handleResponse)
.catch(error => {
console.error(error);
});
}
function signOut() {
/**
* You can pass a custom request object below. This will override the initial configuration. For more information, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
*/
const logoutRequest = {
account: myMSALObj.getAccountByUsername(username),
postLogoutRedirectUri: msalConfig.auth.redirectUri,
mainWindowRedirectUri: msalConfig.auth.redirectUri
};
myMSALObj.logoutPopup(logoutRequest);
}
function getTokenPopup(request) {
/**
* See here for more info on account retrieval:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
*/
request.account = myMSALObj.getAccountByUsername(username);
return myMSALObj.acquireTokenSilent(request)
.catch(error => {
console.warn("silent token acquisition fails. acquiring token using popup");
if (error instanceof msal.InteractionRequiredAuthError) {
// fallback to interaction when silent call fails
return myMSALObj.acquireTokenPopup(request)
.then(tokenResponse => {
console.log(tokenResponse);
return tokenResponse;
}).catch(error => {
console.error(error);
});
} else {
console.warn(error);
}
});
}
function seeProfile() {
getTokenPopup(loginRequest)
.then(response => {
callMSGraph(graphConfig.graphMeEndpoint, response.accessToken, updateUI);
}).catch(error => {
console.error(error);
});
}
function readMail() {
getTokenPopup(tokenRequest)
.then(response => {
callMSGraph(graphConfig.graphMailEndpoint, response.accessToken, updateUI);
}).catch(error => {
console.error(error);
});
}
selectAccount();
Перенаправление
Создайте файл с именем authRedirect.js в папке app и добавьте следующий код для проверки подлинности и получения маркера для перенаправления входа:
// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication(msalConfig);
let username = "";
/**
* A promise handler needs to be registered for handling the
* response returned from redirect flow. For more information, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/acquire-token.md
*/
myMSALObj.handleRedirectPromise()
.then(handleResponse)
.catch((error) => {
console.error(error);
});
function selectAccount () {
/**
* See here for more info on account retrieval:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
*/
const currentAccounts = myMSALObj.getAllAccounts();
if (currentAccounts.length === 0) {
return;
} else if (currentAccounts.length > 1) {
// Add your account choosing logic here
console.warn("Multiple accounts detected.");
} else if (currentAccounts.length === 1) {
username = currentAccounts[0].username;
showWelcomeMessage(username);
}
}
function handleResponse(response) {
if (response !== null) {
username = response.account.username;
showWelcomeMessage(username);
} else {
selectAccount();
}
}
function signIn() {
/**
* You can pass a custom request object below. This will override the initial configuration. For more information, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
*/
myMSALObj.loginRedirect(loginRequest);
}
function signOut() {
/**
* You can pass a custom request object below. This will override the initial configuration. For more information, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
*/
const logoutRequest = {
account: myMSALObj.getAccountByUsername(username),
postLogoutRedirectUri: msalConfig.auth.redirectUri,
};
myMSALObj.logoutRedirect(logoutRequest);
}
function getTokenRedirect(request) {
/**
* See here for more info on account retrieval:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
*/
request.account = myMSALObj.getAccountByUsername(username);
return myMSALObj.acquireTokenSilent(request)
.catch(error => {
console.warn("silent token acquisition fails. acquiring token using redirect");
if (error instanceof msal.InteractionRequiredAuthError) {
// fallback to interaction when silent call fails
return myMSALObj.acquireTokenRedirect(request);
} else {
console.warn(error);
}
});
}
function seeProfile() {
getTokenRedirect(loginRequest)
.then(response => {
callMSGraph(graphConfig.graphMeEndpoint, response.accessToken, updateUI);
}).catch(error => {
console.error(error);
});
}
function readMail() {
getTokenRedirect(tokenRequest)
.then(response => {
callMSGraph(graphConfig.graphMailEndpoint, response.accessToken, updateUI);
}).catch(error => {
console.error(error);
});
}
Принцип работы кода
Когда пользователь впервые нажимает кнопку Войти, метод signIn
вызывает loginPopup
, чтобы пользователь мог выполнить вход. Метод loginPopup
открывает всплывающее окно с конечной точкой платформы удостоверений Майкрософт, чтобы запросить и проверить учетные данные пользователя. После успешного входа msal.js инициирует поток кода авторизации.
На этом этапе код авторизации, защищенный с помощью PKCE, отправляется в конечную точку маркеров, защищенную с помощью CORS, и обменивается на маркеры. Приложение получает маркер идентификатора, маркер доступа и маркер обновления, msal.js их обрабатывает, а информация из этих маркеров кэшируется.
Маркер идентификатора содержит основные сведения о пользователе, например отображаемое имя. Если вы планируете использовать какие-либо данные, предоставляемые этим маркером идентификации, внутренний сервер должен его проверить и подтвердить, что маркер выдан допустимому пользователю для вашего приложения.
Срок действия маркера доступа ограничен и истекает через 24 часа. Маркер обновления можно использовать для автоматического получения новый маркеров доступа.
Одностраничное приложение, созданное в соответствии с инструкциями в этом учебнике, вызывает acquireTokenSilent
и (или) acquireTokenPopup
, чтобы получить маркер доступа, используемый при запросе API Microsoft Graph для получения сведений из профиля пользователя. Если вам нужен пример с проверкой маркера идентификатора, ознакомьтесь с примером приложения active-directory-javascript-singlepageapp-dotnet-webapi-v2 на сайте GitHub. В нем для проверки маркеров используется веб-API ASP.NET.
Интерактивное получение маркера
После первоначального входа приложение не должно требовать от пользователей повторно проходить проверку подлинности при каждой попытке доступа к защищенному ресурсу (то есть запрашивать маркер). Чтобы избежать запросов на повторную проверку подлинности, вызовите acquireTokenSilent
. Но иногда требуется настроить принудительное взаимодействие пользователей с платформой удостоверений Майкрософт. Например:
- Пользователям нужно повторно вводить учетные данные, когда истекает срок действия пароля.
- Приложение запрашивает доступ к ресурсу, на обращение к которому пользователь должен дать согласие.
- Требуется двухфакторная проверка подлинности.
При вызове acquireTokenPopup
открывается всплывающее окно (или acquireTokenRedirect
перенаправляет пользователей на платформу удостоверений Майкрософт). В этом окне пользователям необходимо подтвердить учетные данные, предоставить согласие на требуемый ресурс или выполнить двухфакторную проверку подлинности.
Автоматическое получение маркера пользователя
Метод acquireTokenSilent
отвечает за получение и обновление маркера без участия пользователя. После первого выполнения метода loginPopup
или loginRedirect
обычно используется метод acquireTokenSilent
, чтобы получить маркеры для доступа к защищенным ресурсам для последующих вызовов. (Вызовы для запроса или обновления маркеров не требуют взаимодействия с пользователем.) В некоторых случаях выполнение acquireTokenSilent
может завершаться сбоем. Например, так происходит, когда истекает срок действия пароля пользователя. Приложение может обработать это исключение двумя способами:
- Немедленно вызвать
acquireTokenPopup
, чтобы активировать запрос на вход для пользователя. Этот шаблон обычно используется в интерактивных приложениях, где пользователю недоступно не прошедшее проверку подлинности содержимое. Пример, созданный в ходе пошаговой настройки, использует этот шаблон. - Визуально уведомить пользователя, что требуется интерактивный вход, чтобы пользователь мог выбрать подходящее время для входа или приложение могло повторить метод
acquireTokenSilent
позднее. Обычно этот способ применим в тех случаях, когда пользователь может использовать другие функции приложения, на которые это не влияет. Например, в приложении есть содержимое, для доступа к аутентификация не требуется. В этой ситуации пользователь может самостоятельно решить, когда выполнять вход для получения доступа к защищенному ресурсу или обновления устаревших данных.
Примечание.
В этом учебнике по умолчанию используются методы loginPopup
и acquireTokenPopup
. Если вы используете Internet Explorer, рекомендуется использовать методы loginRedirect
и acquireTokenRedirect
из-за известной проблемы со всплывающими окнами в этом браузере. Пример достижения такого же результата с помощью методов перенаправления см. на странице authRedirect.js на сайте GitHub.
Вызов API Microsoft Graph
Создайте файл с именем graph.js в папке app и добавьте следующий код для отправки вызовов REST в API Microsoft Graph.
/**
* Helper function to call MS Graph API endpoint
* using the authorization bearer token scheme
*/
function callMSGraph(endpoint, token, callback) {
const headers = new Headers();
const bearer = `Bearer ${token}`;
headers.append("Authorization", bearer);
const options = {
method: "GET",
headers: headers
};
console.log('request made to Graph API at: ' + new Date().toString());
fetch(endpoint, options)
.then(response => response.json())
.then(response => callback(response, endpoint))
.catch(error => console.log(error));
}
В примере приложения, созданном в соответствии с инструкциями в этом учебнике, для отправки HTTP-запроса GET
защищенному ресурсу, которому требуется маркер, используется метод callMSGraph()
. Затем метод возвращает содержимое вызывающему объекту. Этот метод добавляет полученный маркер в заголовок авторизации HTTP. Для примера приложения, созданного с помощью этого учебника, защищенным ресурсом является конечная точка me из API Microsoft Graph, которая отображает сведения о профиле выполнившего вход пользователя.
Тестирование приложения
Вы завершили создание приложения и теперь готовы запустить веб-сервер Node.js и протестировать функциональность приложения.
Запустите веб-сервер Node.js, выполнив следующие команды в командной строке из корневой папки проекта:
npm start
В браузере перейдите по адресу
http://localhost:3000
илиhttp://localhost:<port>
, где<port>
— это порт, прослушиваемый вашим веб-сервером. Появится содержимое файла index.html с кнопкой Sign In (Войти).
Вход в приложение
После загрузки файла index.html в браузер нажмите кнопку Sign In (Войти). Вам будет предложено войти с помощью платформы удостоверений Майкрософт:
Предоставление разрешения на доступ к приложению
При первом входе в приложение вам будет предложено предоставить ему доступ к профилю, а также выполнить вход:
Если вы согласились на запрошенные разрешения, веб-приложение отображает имя пользователя, подписав успешное имя входа:
Вызов API Graph
После входа выберите See Profile (Просмотреть профиль), чтобы просмотреть сведения о профиле пользователя, возвращенные в ответе на вызов API Microsoft Graph.
Дополнительные сведения об областях и делегированных разрешениях
Для чтения профиля пользователя API Microsoft Graph требуется область user.read. По умолчанию этот область автоматически добавляется в каждое приложение, зарегистрированное в Центре администрирования Microsoft Entra. Для других API Microsoft Graph, а также для пользовательских API вашего внутреннего сервера, могут потребоваться дополнительные области. Например, для отображения сообщений электронной почты пользователя API Microsoft Graph требуется область Mail.Read.
При добавлении областей приложение может запросить у пользователей дополнительное согласие на использование таких добавленных областей.
Если API серверной части не требуется область (что не рекомендуется), вы можете использовать clientId
в качестве области в вызовах для получения маркеров.
Справка и поддержка
Если вам нужна помощь, если вы хотите сообщить о проблеме или узнать о доступных вариантах поддержки, воспользуйтесь статьей Возможности получения поддержки и справки для разработчиков.
Следующие шаги
- Дополнительные сведения см. в статье о создании одностраничного приложения React, которое входит в систему пользователей в следующей серии руководств по нескольким частьм.