Authenticate with an ArcGIS identity (Browser)

An ArcGIS identity, also known as named user, grants a short-lived access token giving your application permission to access the content and services authorized to your application user's existing ArcGIS Online or ArcGIS Enterprise account.

This temporary token is created using the OAuth 2.0 protocol. It authorizes your application to act on the user's behalf without revealing their secure password to your application. If your application will access your users' secure content in ArcGIS or if you plan to distribute your application through ArcGIS Marketplace, you must use ArcGIS identity authentication.

This tutorial demonstrates using the OAuth2.0 serverless web application workflow to implement the ArcGISIdentityManager class in ArcGIS REST JS and create an identity for a browser application.

Prerequisites

  • You need an account to register a new OAuth 2.0 application. If you do not have an ArcGIS account you can sign up for a free ArcGIS Developer account.

  • Create and register a new OAuth 2.0 application and obtain its Client ID.

  • Update your registered application to specify the Redirect URLs to use for authentication, in the format "https://<server>[:port]" or http://my-arcgis-app:/auth. For example, if you are running your application on https://localhost:8080 add https://localhost:8080/authenticate.html, to the list of redirect URLs. You will create the authenticate.html page later in this tutorial.

To learn more, visit the Register your application tutorial.

Steps

Scaffold HTML

Begin by creating a basic HTML page containing a button directing the user to the authorization page or pop-up. This will be the primary application page.

  1. Create an HTML file to be used for your application and add references to the ArcGIS RestJS library.

    index.html
    Use dark colors for code blocks
                                                                                                                                 
    Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    <!DOCTYPE html>
    
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>ArcGIS REST JS Browser OAuth2</title>
    
        <link
          rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
          crossorigin="anonymous"
        />
        <style>
          body {
            font-family: monospace;
            color: black;
            font-size: 20px;
            overflow: auto;
            padding: 1rem;
          .col-xs-12 {
            margin-top: 10%;
          #withPopupButton,
          #signOutButton {
            font-size: 20px;
        </style>
      </head>
      <body>
        <div id="app-wrapper">
          <div class="container">
            <div class="row">
              <div class="col-xs-12">
                <!-- Event listeners planned to be added to these buttons. -->
                <button class="btn btn-primary btn-block" id="withPopupButton">Sign In</button>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <p id="sessionInfo" class="info-panel">
                  <!-- Information will be injected here. -->
                </p>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <!-- Event listeners will be added to these buttons. -->
                <button class="btn btn-primary btn-block btn-warning" id="signOutButton">Sign Out</button>
              </div>
            </div>
          </div>
        </div>
    
        <script type="module">
          import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
    
          let session = null;
          const clientId = "CLIENT_ID";
          const redirectUri = window.location.origin + "/authenticate.html";
          const serializedSession = localStorage.getItem("__ARCGIS_REST_USER_SESSION__"); // Check to see if there is a serialized session in local storage.
          if (serializedSession !== null && serializedSession !== "undefined") {
          function updateSessionInfo(session) {
            let sessionInfo = document.getElementById("sessionInfo");
            if (session) {
              sessionInfo.classList.remove("bg-info");
              sessionInfo.classList.add("bg-success");
              sessionInfo.innerHTML = "Logged in as " + session.username;
              localStorage.setItem("__ARCGIS_REST_USER_SESSION__", session.serialize());
            } else {
              sessionInfo.classList.remove("bg-success");
              sessionInfo.classList.add("bg-info");
              sessionInfo.innerHTML = "Log in to start a session.";
          document.getElementById("withPopupButton").addEventListener("click", (event) => {
            // Begin an OAuth2 login using a popup.
              clientId: clientId,
              redirectUri: redirectUri,
              popup: true
              .then((newSession) => {
                // Upon a successful login, update the session with the new session.
                console.log(session);
              .catch((error) => {
                console.log(error);
          document.getElementById("signOutButton").addEventListener("click", (event) => {
            // call the signOut method to invalidate the token.
            session.signOut().then(()=>{
              session = null; // Clear the session from memory.
              localStorage.removeItem("__ARCGIS_REST_USER_SESSION__");
        </script>
    
      </body>
    </html>
  2. Import the Bootstrap CSS framework and add Sign in and Sign Out buttons, as well as a sessionInfo area to place user information.

    index.html
    Use dark colors for code blocks
                                                                                                                                 
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    <!DOCTYPE html>
    
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>ArcGIS REST JS Browser OAuth2</title>
    
        <link
          rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
          crossorigin="anonymous"
        />
        <style>
          body {
            font-family: monospace;
            color: black;
            font-size: 20px;
          }
          pre {
            overflow: auto;
            padding: 1rem;
          }
    
          .col-xs-12 {
            margin-top: 10%;
          }
    
          #withPopupButton,
          #signOutButton {
            font-size: 20px;
          }
        </style>
      </head>
      <body>
        <div id="app-wrapper">
          <div class="container">
            <div class="row">
              <div class="col-xs-12">
                <!-- Event listeners planned to be added to these buttons. -->
                <button class="btn btn-primary btn-block" id="withPopupButton">Sign In</button>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <p id="sessionInfo" class="info-panel">
                  <!-- Information will be injected here. -->
                </p>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <!-- Event listeners will be added to these buttons. -->
                <button class="btn btn-primary btn-block btn-warning" id="signOutButton">Sign Out</button>
              </div>
            </div>
          </div>
        </div>
    
        <script type="module">
          import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
    
          let session = null;
          const clientId = "CLIENT_ID";
          const redirectUri = window.location.origin + "/authenticate.html";
          const serializedSession = localStorage.getItem("__ARCGIS_REST_USER_SESSION__"); // Check to see if there is a serialized session in local storage.
          if (serializedSession !== null && serializedSession !== "undefined") {
          function updateSessionInfo(session) {
            let sessionInfo = document.getElementById("sessionInfo");
            if (session) {
              sessionInfo.classList.remove("bg-info");
              sessionInfo.classList.add("bg-success");
              sessionInfo.innerHTML = "Logged in as " + session.username;
              localStorage.setItem("__ARCGIS_REST_USER_SESSION__", session.serialize());
            } else {
              sessionInfo.classList.remove("bg-success");
              sessionInfo.classList.add("bg-info");
              sessionInfo.innerHTML = "Log in to start a session.";
          document.getElementById("withPopupButton").addEventListener("click", (event) => {
            // Begin an OAuth2 login using a popup.
              clientId: clientId,
              redirectUri: redirectUri,
              popup: true
              .then((newSession) => {
                // Upon a successful login, update the session with the new session.
                console.log(session);
              .catch((error) => {
                console.log(error);
          document.getElementById("signOutButton").addEventListener("click", (event) => {
            // call the signOut method to invalidate the token.
            session.signOut().then(()=>{
              session = null; // Clear the session from memory.
              localStorage.removeItem("__ARCGIS_REST_USER_SESSION__");
        </script>
    
      </body>
    </html>

Define authentication variables

  1. Go to the ArcGIS Developer dashboard > OAuth2.0 tab and copy your application's Client ID.

  2. Create session and clientId elements. Set the clientId with the Client ID copied from the dashboard.

  3. Set the redirect_uri to the redirect URI you configured for your application.

    index.html
    Use dark colors for code blocks
                                                                                                                                 
    Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    <!DOCTYPE html>
    
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>ArcGIS REST JS Browser OAuth2</title>
    
        <link
          rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
          crossorigin="anonymous"
        />
        <style>
          body {
            font-family: monospace;
            color: black;
            font-size: 20px;
            overflow: auto;
            padding: 1rem;
          .col-xs-12 {
            margin-top: 10%;
          #withPopupButton,
          #signOutButton {
            font-size: 20px;
        </style>
      </head>
      <body>
        <div id="app-wrapper">
          <div class="container">
            <div class="row">
              <div class="col-xs-12">
                <!-- Event listeners planned to be added to these buttons. -->
                <button class="btn btn-primary btn-block" id="withPopupButton">Sign In</button>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <p id="sessionInfo" class="info-panel">
                  <!-- Information will be injected here. -->
                </p>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <!-- Event listeners will be added to these buttons. -->
                <button class="btn btn-primary btn-block btn-warning" id="signOutButton">Sign Out</button>
              </div>
            </div>
          </div>
        </div>
    
        <script type="module">
          import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
    
          let session = null;
          const clientId = "CLIENT_ID";
          const redirectUri = window.location.origin + "/authenticate.html";
    
          const serializedSession = localStorage.getItem("__ARCGIS_REST_USER_SESSION__"); // Check to see if there is a serialized session in local storage.
          if (serializedSession !== null && serializedSession !== "undefined") {
          function updateSessionInfo(session) {
            let sessionInfo = document.getElementById("sessionInfo");
            if (session) {
              sessionInfo.classList.remove("bg-info");
              sessionInfo.classList.add("bg-success");
              sessionInfo.innerHTML = "Logged in as " + session.username;
              localStorage.setItem("__ARCGIS_REST_USER_SESSION__", session.serialize());
            } else {
              sessionInfo.classList.remove("bg-success");
              sessionInfo.classList.add("bg-info");
              sessionInfo.innerHTML = "Log in to start a session.";
          document.getElementById("withPopupButton").addEventListener("click", (event) => {
            // Begin an OAuth2 login using a popup.
              clientId: clientId,
              redirectUri: redirectUri,
              popup: true
              .then((newSession) => {
                // Upon a successful login, update the session with the new session.
                console.log(session);
              .catch((error) => {
                console.log(error);
          document.getElementById("signOutButton").addEventListener("click", (event) => {
            // call the signOut method to invalidate the token.
            session.signOut().then(()=>{
              session = null; // Clear the session from memory.
              localStorage.removeItem("__ARCGIS_REST_USER_SESSION__");
        </script>
    
      </body>
    </html>

Create a callback page

Once the user is authorized, the access token must be retrieved and passed from the pop-up to the main application page the ArcGISIdentityManager.completeOAuth2 method will automatically handle this.

  1. Open an editor and create an authenticate.html file with references to the ArcGIS REST JS library.

    authenticate.html
    Use dark colors for code blocks
                           
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>ArcGIS Rest JS OAuth redirect</title>
      </head>
      <body>
    
        <script type="module">
          import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
    
          const clientId = "CLIENT_ID";
          const redirectUri = window.location.origin + "/authenticate.html";
        </script>
    
      </body>
    </html>
  2. Set the same clientId and redirectUri parameters that you used in the define authentication variables step.

    authenticate.html
    Use dark colors for code blocks
                           
    Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>ArcGIS Rest JS OAuth redirect</title>
      </head>
      <body>
    
        <script type="module">
          import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
    
          const clientId = "CLIENT_ID";
          const redirectUri = window.location.origin + "/authenticate.html";
    
        </script>
    
      </body>
    </html>
  3. Call the ArcGISIdentityManager.completeOAuth2 method. This will get the access token, pass it back to the main application page and close the popup window.

    authenticate.html
    Use dark colors for code blocks
                           
    Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>ArcGIS Rest JS OAuth redirect</title>
      </head>
      <body>
    
        <script type="module">
          import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
          const clientId = "CLIENT_ID";
          const redirectUri = window.location.origin + "/authenticate.html";
    
          ArcGISIdentityManager.completeOAuth2({
            clientId,
            redirectUri
          })
        </script>
    
      </body>
    </html>

Add event listeners

With the primary application page and callback page configured, you can implement the basic sign-in process by adding event listeners to the buttons.

  1. Save authenticate.html and return to your first HTML file.

  2. Add an event listener:

    • When the user clicks the Sign in button, call the beginOAuth2 method.

    • Set the clientId and redirectUri options.

    • Update the session once the user successfully logs in.

      index.html
      Use dark colors for code blocks
                                                                                                                                   
      Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      <!DOCTYPE html>
      
      <html lang="en">
        <head>
          <meta charset="utf-8" />
          <title>ArcGIS REST JS Browser OAuth2</title>
      
          <link
            rel="stylesheet"
            href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
            integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
            crossorigin="anonymous"
          />
          <style>
            body {
              font-family: monospace;
              color: black;
              font-size: 20px;
              overflow: auto;
              padding: 1rem;
            .col-xs-12 {
              margin-top: 10%;
            #withPopupButton,
            #signOutButton {
              font-size: 20px;
          </style>
        </head>
        <body>
          <div id="app-wrapper">
            <div class="container">
              <div class="row">
                <div class="col-xs-12">
                  <!-- Event listeners planned to be added to these buttons. -->
                  <button class="btn btn-primary btn-block" id="withPopupButton">Sign In</button>
                </div>
              </div>
      
              <div class="row">
                <div class="col-xs-12 text-center">
                  <p id="sessionInfo" class="info-panel">
                    <!-- Information will be injected here. -->
                  </p>
                </div>
              </div>
      
              <div class="row">
                <div class="col-xs-12 text-center">
                  <!-- Event listeners will be added to these buttons. -->
                  <button class="btn btn-primary btn-block btn-warning" id="signOutButton">Sign Out</button>
                </div>
              </div>
            </div>
          </div>
      
          <script type="module">
            import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
            let session = null;
            const clientId = "CLIENT_ID";
            const redirectUri = window.location.origin + "/authenticate.html";
      
            const serializedSession = localStorage.getItem("__ARCGIS_REST_USER_SESSION__"); // Check to see if there is a serialized session in local storage.
            if (serializedSession !== null && serializedSession !== "undefined") {
            function updateSessionInfo(session) {
              let sessionInfo = document.getElementById("sessionInfo");
              if (session) {
                sessionInfo.classList.remove("bg-info");
                sessionInfo.classList.add("bg-success");
                sessionInfo.innerHTML = "Logged in as " + session.username;
                localStorage.setItem("__ARCGIS_REST_USER_SESSION__", session.serialize());
              } else {
                sessionInfo.classList.remove("bg-success");
                sessionInfo.classList.add("bg-info");
                sessionInfo.innerHTML = "Log in to start a session.";
            document.getElementById("withPopupButton").addEventListener("click", (event) => {
              // Begin an OAuth2 login using a popup.
              ArcGISIdentityManager.beginOAuth2({
                clientId: clientId,
                redirectUri: redirectUri,
                popup: true
              })
                .then((newSession) => {
                  // Upon a successful login, update the session with the new session.
                  session = newSession;
                  console.log(session);
                  updateSessionInfo(session);
                })
                .catch((error) => {
                  console.log(error);
                });
              event.preventDefault();
            });
            document.getElementById("signOutButton").addEventListener("click", (event) => {
              // call the signOut method to invalidate the token.
              session.signOut().then(()=>{
                session = null; // Clear the session from memory.
                localStorage.removeItem("__ARCGIS_REST_USER_SESSION__");
          </script>
      
        </body>
      </html>
  3. Add an event listener to clear the session when the user signs out.

    index.html
    Use dark colors for code blocks
                                                                                                                                 
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    <!DOCTYPE html>
    
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>ArcGIS REST JS Browser OAuth2</title>
    
        <link
          rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
          crossorigin="anonymous"
        />
        <style>
          body {
            font-family: monospace;
            color: black;
            font-size: 20px;
            overflow: auto;
            padding: 1rem;
          .col-xs-12 {
            margin-top: 10%;
          #withPopupButton,
          #signOutButton {
            font-size: 20px;
        </style>
      </head>
      <body>
        <div id="app-wrapper">
          <div class="container">
            <div class="row">
              <div class="col-xs-12">
                <!-- Event listeners planned to be added to these buttons. -->
                <button class="btn btn-primary btn-block" id="withPopupButton">Sign In</button>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <p id="sessionInfo" class="info-panel">
                  <!-- Information will be injected here. -->
                </p>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <!-- Event listeners will be added to these buttons. -->
                <button class="btn btn-primary btn-block btn-warning" id="signOutButton">Sign Out</button>
              </div>
            </div>
          </div>
        </div>
    
        <script type="module">
          import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
          let session = null;
          const clientId = "CLIENT_ID";
          const redirectUri = window.location.origin + "/authenticate.html";
          const serializedSession = localStorage.getItem("__ARCGIS_REST_USER_SESSION__"); // Check to see if there is a serialized session in local storage.
          if (serializedSession !== null && serializedSession !== "undefined") {
          function updateSessionInfo(session) {
            let sessionInfo = document.getElementById("sessionInfo");
            if (session) {
              sessionInfo.classList.remove("bg-info");
              sessionInfo.classList.add("bg-success");
              sessionInfo.innerHTML = "Logged in as " + session.username;
              localStorage.setItem("__ARCGIS_REST_USER_SESSION__", session.serialize());
            } else {
              sessionInfo.classList.remove("bg-success");
              sessionInfo.classList.add("bg-info");
              sessionInfo.innerHTML = "Log in to start a session.";
          document.getElementById("withPopupButton").addEventListener("click", (event) => {
            // Begin an OAuth2 login using a popup.
            ArcGISIdentityManager.beginOAuth2({
              clientId: clientId,
              redirectUri: redirectUri,
              popup: true
            })
              .then((newSession) => {
                // Upon a successful login, update the session with the new session.
                session = newSession;
                console.log(session);
                updateSessionInfo(session);
              })
              .catch((error) => {
                console.log(error);
              });
            event.preventDefault();
          });
    
          document.getElementById("signOutButton").addEventListener("click", (event) => {
            event.preventDefault();
            // call the signOut method to invalidate the token.
            session.signOut().then(()=>{
              session = null; // Clear the session from memory.
              localStorage.removeItem("__ARCGIS_REST_USER_SESSION__");
              updateSessionInfo();
            });
          });
        </script>
    
      </body>
    </html>

Create a session from local storage

ArcGIS REST JS does not include tools for persisting a session after retrieving session information. You must decide how to implement persisting the session and specify where the user goes after they authorize your application.

  1. Create a serializedSession function that checks if there is a session in local storage. You can use the ArcGISIdentityManager.deserialize method to parse the serializedSession data.

    index.html
    Use dark colors for code blocks
                                                                                                                                 
    Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    <!DOCTYPE html>
    
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>ArcGIS REST JS Browser OAuth2</title>
    
        <link
          rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
          crossorigin="anonymous"
        />
        <style>
          body {
            font-family: monospace;
            color: black;
            font-size: 20px;
            overflow: auto;
            padding: 1rem;
          .col-xs-12 {
            margin-top: 10%;
          #withPopupButton,
          #signOutButton {
            font-size: 20px;
        </style>
      </head>
      <body>
        <div id="app-wrapper">
          <div class="container">
            <div class="row">
              <div class="col-xs-12">
                <!-- Event listeners planned to be added to these buttons. -->
                <button class="btn btn-primary btn-block" id="withPopupButton">Sign In</button>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <p id="sessionInfo" class="info-panel">
                  <!-- Information will be injected here. -->
                </p>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <!-- Event listeners will be added to these buttons. -->
                <button class="btn btn-primary btn-block btn-warning" id="signOutButton">Sign Out</button>
              </div>
            </div>
          </div>
        </div>
    
        <script type="module">
          import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
          let session = null;
          const clientId = "CLIENT_ID";
          const redirectUri = window.location.origin + "/authenticate.html";
    
          const serializedSession = localStorage.getItem("__ARCGIS_REST_USER_SESSION__"); // Check to see if there is a serialized session in local storage.
    
          if (serializedSession !== null && serializedSession !== "undefined") {
            session = ArcGISIdentityManager.deserialize(serializedSession);
          }
          function updateSessionInfo(session) {
            let sessionInfo = document.getElementById("sessionInfo");
            if (session) {
              sessionInfo.classList.remove("bg-info");
              sessionInfo.classList.add("bg-success");
              sessionInfo.innerHTML = "Logged in as " + session.username;
              localStorage.setItem("__ARCGIS_REST_USER_SESSION__", session.serialize());
            } else {
              sessionInfo.classList.remove("bg-success");
              sessionInfo.classList.add("bg-info");
              sessionInfo.innerHTML = "Log in to start a session.";
          document.getElementById("withPopupButton").addEventListener("click", (event) => {
            // Begin an OAuth2 login using a popup.
              clientId: clientId,
              redirectUri: redirectUri,
              popup: true
              .then((newSession) => {
                // Upon a successful login, update the session with the new session.
                console.log(session);
              .catch((error) => {
                console.log(error);
          document.getElementById("signOutButton").addEventListener("click", (event) => {
            // call the signOut method to invalidate the token.
            session.signOut().then(()=>{
              session = null; // Clear the session from memory.
              localStorage.removeItem("__ARCGIS_REST_USER_SESSION__");
        </script>
    
      </body>
    </html>

Update session info

  1. Create an updateSessionInfo function that adds the username to sessionInfo if the user is signed in. If not, ask the user to log in with their credentials.

    index.html
    Use dark colors for code blocks
                                                                                                                                 
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    <!DOCTYPE html>
    
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>ArcGIS REST JS Browser OAuth2</title>
    
        <link
          rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
          crossorigin="anonymous"
        />
        <style>
          body {
            font-family: monospace;
            color: black;
            font-size: 20px;
            overflow: auto;
            padding: 1rem;
          .col-xs-12 {
            margin-top: 10%;
          #withPopupButton,
          #signOutButton {
            font-size: 20px;
        </style>
      </head>
      <body>
        <div id="app-wrapper">
          <div class="container">
            <div class="row">
              <div class="col-xs-12">
                <!-- Event listeners planned to be added to these buttons. -->
                <button class="btn btn-primary btn-block" id="withPopupButton">Sign In</button>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <p id="sessionInfo" class="info-panel">
                  <!-- Information will be injected here. -->
                </p>
              </div>
            </div>
    
            <div class="row">
              <div class="col-xs-12 text-center">
                <!-- Event listeners will be added to these buttons. -->
                <button class="btn btn-primary btn-block btn-warning" id="signOutButton">Sign Out</button>
              </div>
            </div>
          </div>
        </div>
    
        <script type="module">
          import { ArcGISIdentityManager } from 'https://cdn.skypack.dev/@esri/arcgis-rest-request@4.0.0';
          let session = null;
          const clientId = "CLIENT_ID";
          const redirectUri = window.location.origin + "/authenticate.html";
          const serializedSession = localStorage.getItem("__ARCGIS_REST_USER_SESSION__"); // Check to see if there is a serialized session in local storage.
    
          if (serializedSession !== null && serializedSession !== "undefined") {
            session = ArcGISIdentityManager.deserialize(serializedSession);
          }
    
          function updateSessionInfo(session) {
            let sessionInfo = document.getElementById("sessionInfo");
    
            if (session) {
              sessionInfo.classList.remove("bg-info");
              sessionInfo.classList.add("bg-success");
              sessionInfo.innerHTML = "Logged in as " + session.username;
              localStorage.setItem("__ARCGIS_REST_USER_SESSION__", session.serialize());
            } else {
              sessionInfo.classList.remove("bg-success");
              sessionInfo.classList.add("bg-info");
              sessionInfo.innerHTML = "Log in to start a session.";
            }
          }
    
          updateSessionInfo(session);
    
          document.getElementById("withPopupButton").addEventListener("click", (event) => {
            // Begin an OAuth2 login using a popup.
              clientId: clientId,
              redirectUri: redirectUri,
              popup: true
              .then((newSession) => {
                // Upon a successful login, update the session with the new session.
                console.log(session);
              .catch((error) => {
                console.log(error);
          document.getElementById("signOutButton").addEventListener("click", (event) => {
            // call the signOut method to invalidate the token.
            session.signOut().then(()=>{
              session = null; // Clear the session from memory.
              localStorage.removeItem("__ARCGIS_REST_USER_SESSION__");
        </script>
    
      </body>
    </html>

Run the app

Run the application and navigate to your localhost, for example: https://localhost:8080. You will see the sign in page:

REST JS sample

When you click Sign in, a pop-up prompts you to enter your credentials. Upon successful authorization, you are redirected to the home page where your username is displayed.

What's next

Learn how to use additional ArcGIS location services in these tutorials:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.