Skip to content

Commit 22fd0bd

Browse files
committed
Merge branch 'public-50160' of https://github.com/ktoliver/azure-docs-pr into public-50160
2 parents ecab0a4 + d489b42 commit 22fd0bd

File tree

1 file changed

+81
-79
lines changed

1 file changed

+81
-79
lines changed

articles/active-directory/develop/tutorial-v2-javascript-spa.md

Lines changed: 81 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ This guide uses the following library:
7070

7171
Make sure you have [Node.js](https://nodejs.org/en/download/) installed, and then create a folder to host your application. There, we will implement a simple [Express](https://expressjs.com/) web server to serve your `index.html` file.
7272

73-
1. First, using Visual Studio Code integrated terminal, locate your project folder, and then install Express using NPM:
73+
1. First, using Visual Studio Code integrated terminal, locate your project folder, and then install Express using NPM.
7474

75-
2. Next, create a .js file named `server.js`, and add the following code:
75+
1. Next, create a .js file named `server.js`, and then add the following code:
7676

7777
```JavaScript
7878
const express = require('express');
@@ -103,22 +103,23 @@ Make sure you have [Node.js](https://nodejs.org/en/download/) installed, and the
103103

104104
You now have a simple server to serve your SPA. The intended folder structure at the end of this tutorial is as follows:
105105

106-
.
107-
└── active-directory-javascript-graphapi-v2/
108-
├── package.json
109-
├── node_modules
110-
├── server.js
111-
└── JavaScriptSPA/
112-
├── index.html
113-
├── ui.js
114-
├── authConfig.js
115-
├── graphConfig.js
116-
└── authPopup.js
106+
.<br />
107+
└── active-directory-javascript-graphapi-v2/<br />
108+
├── package.json<br />
109+
├── node_modules<br />
110+
├── server.js<br />
111+
└── JavaScriptSPA/<br />
112+
├── index.html<br />
113+
├── ui.js<br />
114+
├── authConfig.js<br />
115+
├── graphConfig.js<br />
116+
└── authPopup.js<br />
117117

118118
## Create the SPA UI
119+
119120
1. Create an `index.html` file for your JavaScript SPA. This file implements a UI built with **Bootstrap 4 Framework** and imports script files for configuration, authentication and API call.
120121

121-
In the `index.html` file, add the following code:
122+
In the `index.html` file, add the following code:
122123

123124
```html
124125
<!DOCTYPE html>
@@ -275,7 +276,6 @@ In the `index.html` file, add the following code:
275276
Before proceeding further with authentication, register your application on **Azure Active Directory**.
276277

277278
1. Sign in to the [Azure portal](https://portal.azure.com/).
278-
279279
1. If your account gives you access to more than one tenant, select the account at the upper right, and then set your portal session to the Azure AD tenant that you want to use.
280280
1. Go to the Microsoft identity platform for developers [App registrations](https://go.microsoft.com/fwlink/?linkid=2083908) page.
281281
1. When the **Register an application** page appears, enter a name for your application.
@@ -287,52 +287,53 @@ Before proceeding further with authentication, register your application on **Az
287287
1. In **Advanced settings**, under **Implicit grant**, select the **ID tokens** and **Access tokens** check boxes. ID tokens and access tokens are required because this app must sign in users and call an API.
288288
1. Select **Save**.
289289

290-
> #### Set a redirect URL for Node.js
290+
> ### Set a redirect URL for Node.js
291+
>
291292
> For Node.js, you can set the web server port in the *server.js* file. This tutorial uses port 3000, but you can use any other available port.
292293
>
293294
> To set up a redirect URL in the application registration information, switch back to the **Application Registration** pane, and do either of the following:
294295
>
295296
> - Set *`http://localhost:3000/`* as the **Redirect URL**.
296297
> - If you're using a custom TCP port, use *`http://localhost:<port>/`* (where *\<port>* is the custom TCP port number).
298+
> 1. Copy the **URL** value.
299+
> 1. Switch back to the **Application Registration** pane, and paste the copied value as the **Redirect URL**.
297300
>
298-
> 1. Copy the **URL** value.
299-
> 1. Switch back to the **Application Registration** pane, and paste the copied value as the **Redirect URL**.
300301
301-
#### Configure your JavaScript SPA
302+
### Configure your JavaScript SPA
302303

303304
Create a new .js file named `authConfig.js`, which will contain your configuration parameters for authentication, and add the following code:
304305

305-
```javascript
306-
const msalConfig = {
307-
auth: {
308-
clientId: "Enter_the_Application_Id_Here",
309-
authority: "Enter_the_Cloud_Instance_Id_HereEnter_the_Tenant_Info_Here",
310-
redirectUri: "Enter_the_Redirect_Uri_Here",
311-
},
312-
cache: {
313-
cacheLocation: "sessionStorage", // This configures where your cache will be stored
314-
storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
315-
}
316-
};
317-
318-
// Add here scopes for id token to be used at MS Identity Platform endpoints.
319-
const loginRequest = {
320-
scopes: ["openid", "profile", "User.Read"]
321-
};
306+
```javascript
307+
const msalConfig = {
308+
auth: {
309+
clientId: "Enter_the_Application_Id_Here",
310+
authority: "Enter_the_Cloud_Instance_Id_HereEnter_the_Tenant_Info_Here",
311+
redirectUri: "Enter_the_Redirect_Uri_Here",
312+
},
313+
cache: {
314+
cacheLocation: "sessionStorage", // This configures where your cache will be stored
315+
storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
316+
}
317+
};
318+
319+
// Add here scopes for id token to be used at MS Identity Platform endpoints.
320+
const loginRequest = {
321+
scopes: ["openid", "profile", "User.Read"]
322+
};
322323

323-
// Add here scopes for access token to be used at MS Graph API endpoints.
324-
const tokenRequest = {
325-
scopes: ["Mail.Read"]
326-
};
327-
```
324+
// Add here scopes for access token to be used at MS Graph API endpoints.
325+
const tokenRequest = {
326+
scopes: ["Mail.Read"]
327+
};
328+
```
328329

329330
Where:
330331
- *\<Enter_the_Application_Id_Here>* is the **Application (client) ID** for the application you registered.
331332
- *\<Enter_the_Cloud_Instance_Id_Here>* is the instance of the Azure cloud. For the main or global Azure cloud, simply enter *https://login.microsoftonline.com*. For **national** clouds (for example, China), see [National clouds](https://docs.microsoft.com/azure/active-directory/develop/authentication-national-cloud).
332333
- *\<Enter_the_Tenant_info_here>* is set to one of the following options:
333-
- If your application supports *accounts in this organizational directory*, replace this value with the **Tenant ID** or **Tenant name** (for example, *contoso.microsoft.com*).
334-
- If your application supports *accounts in any organizational directory*, replace this value with **organizations**.
335-
- If your application supports *accounts in any organizational directory and personal Microsoft accounts*, replace this value with **common**. To restrict support to *personal Microsoft accounts only*, replace this value with **consumers**.
334+
- If your application supports *accounts in this organizational directory*, replace this value with the **Tenant ID** or **Tenant name** (for example, *contoso.microsoft.com*).
335+
- If your application supports *accounts in any organizational directory*, replace this value with **organizations**.
336+
- If your application supports *accounts in any organizational directory and personal Microsoft accounts*, replace this value with **common**. To restrict support to *personal Microsoft accounts only*, replace this value with **consumers**.
336337

337338

338339
## Use the Microsoft Authentication Library (MSAL) to sign in the user
@@ -408,7 +409,7 @@ After a user selects the **Sign In** button for the first time, the `signIn` met
408409

409410
The SPA generated by this guide calls `acquireTokenSilent` and/or `acquireTokenPopup` to acquire an *access token* used to query the Microsoft Graph API for user profile info. If you need a sample that validates the ID token, take a look at [this](https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-dotnet-webapi-v2 "GitHub active-directory-javascript-singlepageapp-dotnet-webapi-v2 sample") sample application in GitHub. The sample uses an ASP.NET Web API for token validation.
410411

411-
#### Getting a user token interactively
412+
#### Get a user token interactively
412413

413414
After the initial sign-in, you do not want to ask users to reauthenticate every time they need to request a token to access a resource. So *acquireTokenSilent* should be used most of the time to acquire tokens. There are situations, however, where you need to force users to interact with Microsoft identity platform endpoint. Examples include:
414415

@@ -418,55 +419,56 @@ After the initial sign-in, you do not want to ask users to reauthenticate every
418419

419420
Calling *acquireTokenPopup* opens a pop-up window (or *acquireTokenRedirect* redirects users to the Microsoft identity platform endpoint). In that window, users need to interact by confirming their credentials, giving consent to the required resource, or completing the two-factor authentication.
420421

421-
#### Getting a user token silently
422+
#### Get a user token silently
422423

423424
The `acquireTokenSilent` method handles token acquisition and renewal without any user interaction. After `loginPopup` (or `loginRedirect`) is executed for the first time, `acquireTokenSilent` is the method commonly used to obtain tokens used to access protected resources for subsequent calls. (Calls to request or renew tokens are made silently.)
424425
`acquireTokenSilent` may fail in some cases. For example, the user's password may have expired. Your application can handle this exception in two ways:
425426

426427
1. Make a call to `acquireTokenPopup` immediately, which triggers a user sign-in prompt. This pattern is commonly used in online applications where there is no unauthenticated content in the application available to the user. The sample generated by this guided setup uses this pattern.
427428

428-
2. Applications can also make a visual indication to the user that an interactive sign-in is required, so the user can select the right time to sign in, or the application can retry `acquireTokenSilent` at a later time. This is commonly used when the user can use other functionality of the application without being disrupted. For example, there might be unauthenticated content available in the application. In this situation, the user can decide when they want to sign in to access the protected resource, or to refresh the outdated information.
429+
1. Applications can also make a visual indication to the user that an interactive sign-in is required, so the user can select the right time to sign in, or the application can retry `acquireTokenSilent` at a later time. This is commonly used when the user can use other functionality of the application without being disrupted. For example, there might be unauthenticated content available in the application. In this situation, the user can decide when they want to sign in to access the protected resource, or to refresh the outdated information.
429430

430431
> [!NOTE]
431432
> This quickstart uses the `loginPopup` and `acquireTokenPopup` methods by default. If you are using Internet Explorer as your browser, it is recommended to use `loginRedirect` and `acquireTokenRedirect` methods, due to a [known issue](https://github.com/AzureAD/microsoft-authentication-library-for-js/wiki/Known-issues-on-IE-and-Edge-Browser#issues) related to the way Internet Explorer handles pop-up windows. If you would like to see how to achieve the same result using `Redirect methods`, please [see](https://github.com/Azure-Samples/active-directory-javascript-graphapi-v2/blob/quickstart/JavaScriptSPA/authRedirect.js).
432433
<!--end-collapse-->
433434
434435
## Call the Microsoft Graph API by using the token you just acquired
435436

436-
1. First, create a .js file named `graphConfig.js`, which will store your REST endpoints, and add the following code:
437+
1. First, create a .js file named `graphConfig.js`, which will store your REST endpoints. Add the following code:
437438

438-
```JavaScript
439-
const graphConfig = {
440-
graphMeEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me",
441-
graphMailEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me/messages"
442-
};
443-
```
439+
```JavaScript
440+
const graphConfig = {
441+
graphMeEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me",
442+
graphMailEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me/messages"
443+
};
444+
```
444445

445-
Where:
446-
- *\<Enter_the_Graph_Endpoint_Here>* is the instance of MS Graph API. For the global MS Graph API endpoint, simply replace this string with `https://graph.microsoft.com`. For national cloud deployments, please refer to [Graph API Documentation](https://docs.microsoft.com/en-us/graph/deployments).
446+
Where:
447+
- *\<Enter_the_Graph_Endpoint_Here>* is the instance of MS Graph API. For the global MS Graph API endpoint, simply replace this string with `https://graph.microsoft.com`. For national cloud deployments, please refer to [Graph API Documentation](https://docs.microsoft.com/graph/deployments).
447448

448-
2. Next, create a .js file named `graph.js`, which will make a REST call to Microsoft Graph API, and add the following code:
449+
1. Next, create a .js file named `graph.js`, which will make a REST call to Microsoft Graph API, and add the following code:
449450

450-
```javascript
451-
function callMSGraph(endpoint, token, callback) {
452-
const headers = new Headers();
453-
const bearer = `Bearer ${token}`;
451+
```javascript
452+
function callMSGraph(endpoint, token, callback) {
453+
const headers = new Headers();
454+
const bearer = `Bearer ${token}`;
454455

455-
headers.append("Authorization", bearer);
456+
headers.append("Authorization", bearer);
456457

457-
const options = {
458-
method: "GET",
459-
headers: headers
460-
};
458+
const options = {
459+
method: "GET",
460+
headers: headers
461+
};
461462

462-
console.log('request made to Graph API at: ' + new Date().toString());
463+
console.log('request made to Graph API at: ' + new Date().toString());
463464

464-
fetch(endpoint, options)
465-
.then(response => response.json())
466-
.then(response => callback(response, endpoint))
467-
.catch(error => console.log(error))
468-
}
469-
```
465+
fetch(endpoint, options)
466+
.then(response => response.json())
467+
.then(response => callback(response, endpoint))
468+
.catch(error => console.log(error))
469+
}
470+
```
471+
470472
<!--start-collapse-->
471473

472474
### More information about making a REST call against a protected API
@@ -479,10 +481,10 @@ In the sample application created by this guide, the `callMSGraph()` method is u
479481

480482
1. Configure the server to listen to a TCP port that's based on the location of your *index.html* file. For Node.js, start the web server to listen to the port by running the following commands at a command-line prompt from the application folder:
481483

482-
```bash
483-
npm install
484-
npm start
485-
```
484+
```bash
485+
npm install
486+
npm start
487+
```
486488
1. In your browser, enter **http://localhost:3000** or **http://localhost:{port}**, where *port* is the port that your web server is listening to. You should see the contents of your *index.html* file and the **Sign In** button.
487489

488490
## Test your application
@@ -508,8 +510,8 @@ After you sign in, your user profile information is returned in the Microsoft Gr
508510

509511
The Microsoft Graph API requires the *user.read* scope to read a user's profile. By default, this scope is automatically added in every application that's registered on the registration portal. Other APIs for Microsoft Graph, as well as custom APIs for your back-end server, might require additional scopes. For example, the Microsoft Graph API requires the *Mail.Read* scope in order to list the user’s mails.
510512

511-
>[!NOTE]
512-
>The user might be prompted for additional consents as you increase the number of scopes.
513+
> [!NOTE]
514+
> The user might be prompted for additional consents as you increase the number of scopes.
513515
514516
If a back-end API doesn't require a scope (not recommended), you can use *clientId* as the scope in the calls to acquire tokens.
515517

0 commit comments

Comments
 (0)