You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: articles/active-directory/develop/tutorial-v2-javascript-spa.md
+81-79Lines changed: 81 additions & 79 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -70,9 +70,9 @@ This guide uses the following library:
70
70
71
71
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.
72
72
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.
74
74
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:
76
76
77
77
```JavaScript
78
78
constexpress=require('express');
@@ -103,22 +103,23 @@ Make sure you have [Node.js](https://nodejs.org/en/download/) installed, and the
103
103
104
104
You now have a simple server to serve your SPA. The intended folder structure at the end of this tutorial is as follows:
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.
120
121
121
-
In the `index.html` file, add the following code:
122
+
In the `index.html` file, add the following code:
122
123
123
124
```html
124
125
<!DOCTYPE html>
@@ -275,7 +276,6 @@ In the `index.html` file, add the following code:
275
276
Before proceeding further with authentication, register your application on **Azure Active Directory**.
276
277
277
278
1. Sign in to the [Azure portal](https://portal.azure.com/).
278
-
279
279
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.
280
280
1. Go to the Microsoft identity platform for developers [App registrations](https://go.microsoft.com/fwlink/?linkid=2083908) page.
281
281
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
287
287
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.
288
288
1. Select **Save**.
289
289
290
-
> #### Set a redirect URL for Node.js
290
+
> ### Set a redirect URL for Node.js
291
+
>
291
292
> 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.
292
293
>
293
294
> To set up a redirect URL in the application registration information, switch back to the **Application Registration** pane, and do either of the following:
294
295
>
295
296
> - Set *`http://localhost:3000/`* as the **Redirect URL**.
296
297
> - 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**.
297
300
>
298
-
> 1. Copy the **URL** value.
299
-
> 1. Switch back to the **Application Registration** pane, and paste the copied value as the **Redirect URL**.
300
301
301
-
####Configure your JavaScript SPA
302
+
### Configure your JavaScript SPA
302
303
303
304
Create a new .js file named `authConfig.js`, which will contain your configuration parameters for authentication, and add the following code:
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
+
constloginRequest= {
321
+
scopes: ["openid", "profile", "User.Read"]
322
+
};
322
323
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
+
consttokenRequest= {
326
+
scopes: ["Mail.Read"]
327
+
};
328
+
```
328
329
329
330
Where:
330
331
-*\<Enter_the_Application_Id_Here>* is the **Application (client) ID** for the application you registered.
331
332
-*\<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).
332
333
-*\<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**.
336
337
337
338
338
339
## 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
408
409
409
410
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.
410
411
411
-
#### Getting a user token interactively
412
+
#### Get a user token interactively
412
413
413
414
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:
414
415
@@ -418,55 +419,56 @@ After the initial sign-in, you do not want to ask users to reauthenticate every
418
419
419
420
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.
420
421
421
-
#### Getting a user token silently
422
+
#### Get a user token silently
422
423
423
424
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.)
424
425
`acquireTokenSilent` may fail in some cases. For example, the user's password may have expired. Your application can handle this exception in two ways:
425
426
426
427
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.
427
428
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.
429
430
430
431
> [!NOTE]
431
432
> 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).
432
433
<!--end-collapse-->
433
434
434
435
## Call the Microsoft Graph API by using the token you just acquired
435
436
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:
-*\<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).
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).
447
448
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:
449
450
450
-
```javascript
451
-
functioncallMSGraph(endpoint, token, callback) {
452
-
constheaders=newHeaders();
453
-
constbearer=`Bearer ${token}`;
451
+
```javascript
452
+
functioncallMSGraph(endpoint, token, callback) {
453
+
constheaders=newHeaders();
454
+
constbearer=`Bearer ${token}`;
454
455
455
-
headers.append("Authorization", bearer);
456
+
headers.append("Authorization", bearer);
456
457
457
-
constoptions= {
458
-
method:"GET",
459
-
headers: headers
460
-
};
458
+
constoptions= {
459
+
method:"GET",
460
+
headers: headers
461
+
};
461
462
462
-
console.log('request made to Graph API at: '+newDate().toString());
463
+
console.log('request made to Graph API at: '+newDate().toString());
463
464
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
+
470
472
<!--start-collapse-->
471
473
472
474
### 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
479
481
480
482
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:
481
483
482
-
```bash
483
-
npm install
484
-
npm start
485
-
```
484
+
```bash
485
+
npm install
486
+
npm start
487
+
```
486
488
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.
487
489
488
490
## Test your application
@@ -508,8 +510,8 @@ After you sign in, your user profile information is returned in the Microsoft Gr
508
510
509
511
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.
510
512
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.
513
515
514
516
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.
0 commit comments