Sign in with user authentication (server)

(formerly ArcGIS identity) generates a short-lived , authorizing your application to access , content, and resources on behalf of a logged in ArcGIS user.

The temporary token from user authentication 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 REST JS provides helper methods for the Node.js server environment to handle authentication in your applications. In this tutorial, you use an OAuth2.0 server-enabled workflow. With server-side authentication, you can use the refresh token generated from the session and stored on your server environment to get a short-lived access token for the user.

Prerequisites

Steps

Create OAuth 2.0 credentials

Create a new to register the application.

  1. Go to the Create OAuth credentials for user authentication tutorial to create an OAuth credential.
  2. Copy the Client ID and Redirect URL from your OAuth credentials item and paste them to a safe location. They will be used in a later step.

Set up a configuration file

  1. In the of your OAuth credentials, copy your client ID. Ensure that http//localhost:3000/authenticate is registered as a redirect URL in the item settings.

  2. Generate a session secret and an encryption key. These are used to encrypt session information on the server. You can generate random, secure strings at RandomKeygen.

  3. Open a code editor and create a config.json file. Set the CLIENT_ID and REDIRECT_URI to the values you configured in your . Set the SESSION_SECRET and ENCRYPTION_KEY values to those generated in the previous step. Set the PORTAL_URL value to your portal URL.

    config.json
    1
    2
    3
    4
    5
    6
    7
    {
      "CLIENT_ID": "CLIENT_ID",
      "SESSION_SECRET": "SESSION_SECRET",
      "ENCRYPTION_KEY": "ENCRYPTION_KEY",
      "REDIRECT_URI": "http://localhost:3000/authenticate",
      "PORTAL_URL": "https://{machine.domain.com}/{webadaptor}/sharing/rest"
    }

Import modules

By using the Node.js express server environment along with express-session and session-file-store, the user's session will persist on the server. The session is not stored on the client-side application and there is no permanent, persistent token stored on the user's machine.

  1. In a separate server.js file, import the express, express-session, and session-file-store npm packages, as well as the ArcGIS REST JS ArcGISIdentityManager class.

    server.js
    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
    
    require("cross-fetch/polyfill");
    require("isomorphic-form-data");
    
    const express = require("express");
    const session = require("express-session");
    const FileStore = require("session-file-store")(session);
    const app = express();
    const { ArcGISIdentityManager } = require("@esri/arcgis-rest-request");
    
  2. Create an instance of express and a credentials object to set the clientId, redirectUrl, and portal.

    server.js
    Expand
    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
    const express = require("express");
    const session = require("express-session");
    const FileStore = require("session-file-store")(session);
    const app = express();
    const { ArcGISIdentityManager } = require("@esri/arcgis-rest-request");
    
    const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI, PORTAL_URL } = require("./config.json");
    
    const credentials = {
      clientId: CLIENT_ID,
      redirectUri: REDIRECT_URI,
      portal: PORTAL_URL // OPTIONAL - For ArcGIS Enterprise only
    };
    
    Expand

Get user session

When the user is redirected to the sign in page, the authorize method will be called to take the provided credentials and the response object. After the user is redirected back to the authenticate page, the exchangeAuthorizationCode method will be used to exchange the code from the redirect for a token and instantiate a new user session.

  1. Call the authorize method with credentials and res (the response object) as parameters when the user gets redirected to the sign in page.

    server.js
    Expand
    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
    const credentials = {
      clientId: CLIENT_ID,
      redirectUri: REDIRECT_URI,
      portal: PORTAL_URL // OPTIONAL - For ArcGIS Enterprise only
    };
    
    app.get("/sign-in", (req, res) => {
      ArcGISIdentityManager.authorize(credentials, res);
    });
    
    
    Expand
  2. Destroy the cookie and session file when the user signs out and returns to the home page.

    server.js
    Expand
    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
    app.get("/sign-in", (req, res) => {
      ArcGISIdentityManager.authorize(credentials, res);
    });
    
    app.get("/sign-out", (req, res) => {
      // invalidate the token
      ArcGISIdentityManager.destroy(req.session.arcgis).then(() => {
        // delete the cookie and stored session
      });
    });
    
    Expand
  3. Redirect the user to the authorization page. Call the exchangeAuthorizationCode to use the credentials and exchange the code for a token in the session.

    server.js
    Expand
    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
    app.get("/sign-out", (req, res) => {
      // invalidate the token
      ArcGISIdentityManager.destroy(req.session.arcgis).then(() => {
        // delete the cookie and stored session
      });
    });
    
    app.get("/authenticate", async (req, res) => {
      req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode(
        credentials,
        req.query.code //The code from the redirect: exchange code for a token in instaniated user session.
      );
    
    
    Expand
  4. Redirect the user to the home page and display session information when the user provides credentials.

    server.js
    Expand
    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
    });
    
    app.get("/", (req, res) => {
      //Redirect to homepage.
      if (req.session.arcgis) {
        res.send(`
        <h1>Hi ${req.session.arcgis.username}<h1>
        <pre><code>${JSON.stringify(req.session.arcgis, null, 2)}</code></pre>
        <a href="/sign-out">Sign Out<a>
      `);
      } else {
        res.send(`<a href="/sign-in">Sign In<a>`);
      }
    });
    
    

Store the session

When you set up a session, express will set a cookie on the client to keep track of the session ID and persist the corresponding session on the server. By assigning the userSession to the request, the session ID is saved on the user's machine as a secure, encrypted file.

  1. Save the sesssion on the user's machine and redirect the user to the homepage.

    server.js
    Expand
    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
    app.get("/sign-out", (req, res) => {
      // invalidate the token
      ArcGISIdentityManager.destroy(req.session.arcgis).then(() => {
        // delete the cookie and stored session
        req.session.destroy();
      });
    });
    
    app.get("/authenticate", async (req, res) => {
      req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode(
        credentials,
        req.query.code //The code from the redirect: exchange code for a token in instaniated user session.
      );
    
      res.redirect("/");
    
    });
    
    Expand
  2. Call the use method of express to start implementing express-session. Set the secret to your application's SESSION_SECRET. This is used to encrypt the cookies and session information.

    server.js
    Expand
    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
    const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI, PORTAL_URL } = require("./config.json");
    
    const credentials = {
      clientId: CLIENT_ID,
      redirectUri: REDIRECT_URI,
      portal: PORTAL_URL // OPTIONAL - For ArcGIS Enterprise only
    };
    
    app.use(
      session({
        name: "ArcGIS REST JS server authentication tutorial",
        secret: SESSION_SECRET,
        resave: false,
        saveUninitialized: false,
        cookie: {
          maxAge: 2592000000 // 30 days in milliseconds
        },
    
    
    Expand
  3. Create a FileStore to save the sessions on your server as files., and set the secret with the ENCRYPTION_KEY you configured in the config.json file.

    server.js
    Expand
    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
    app.use(
      session({
        name: "ArcGIS REST JS server authentication tutorial",
        secret: SESSION_SECRET,
        resave: false,
        saveUninitialized: false,
        cookie: {
          maxAge: 2592000000 // 30 days in milliseconds
        },
    
        store: new FileStore({
          ttl: 2592000000 / 1000, // 30 days in seconds
          retries: 1,
          secret: ENCRYPTION_KEY,
    
        })
    
    Expand
  4. Set the encoder option with the sessionObj to serialize the session object before it is encrypted and stored on disk. The decoder decodes the sessionContent using the encryption key the user specifies.

    server.js
    Expand
    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
    app.use(
      session({
        name: "ArcGIS REST JS server authentication tutorial",
        secret: SESSION_SECRET,
        resave: false,
        saveUninitialized: false,
        cookie: {
          maxAge: 2592000000 // 30 days in milliseconds
        },
    
        store: new FileStore({
          ttl: 2592000000 / 1000, // 30 days in seconds
          retries: 1,
          secret: ENCRYPTION_KEY,
    
          // define how to encode our session to text for storing in the file. We can use the `serialize()` method on the session for this.
          encoder: (sessionObj) => {
            console.log({ sessionObj });
            sessionObj.arcgis = sessionObj.arcgis.serialize();
            return JSON.stringify(sessionObj);
          },
    
          // define how to turn the text from the session data back into an object. We can use the `ArcGISIdentityManager.deserialize()` method for this.
          decoder: (sessionContents) => {
            console.log({ sessionContents });
            const sessionObj = JSON.parse(sessionContents);
            if (sessionObj.arcgis) {
              sessionObj.arcgis = ArcGISIdentityManager.deserialize(sessionObj.arcgis);
            }
    
            return sessionObj;
          }
    
        })
    
    Expand
  5. Set the decode option to deserialize the sessionObj into a JavaScript object.

    server.js
    Expand
    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
          // define how to encode our session to text for storing in the file. We can use the `serialize()` method on the session for this.
          encoder: (sessionObj) => {
            console.log({ sessionObj });
            sessionObj.arcgis = sessionObj.arcgis.serialize();
            return JSON.stringify(sessionObj);
          },
    
          // define how to turn the text from the session data back into an object. We can use the `ArcGISIdentityManager.deserialize()` method for this.
          decoder: (sessionContents) => {
            console.log({ sessionContents });
            const sessionObj = JSON.parse(sessionContents);
            if (sessionObj.arcgis) {
              sessionObj.arcgis = ArcGISIdentityManager.deserialize(sessionObj.arcgis);
            }
    
            return sessionObj;
          }
    
    Expand

Run the app

  1. Call the listen method and place a console.log to allow the user to navigate to http://localhost:3000/.

    server.js
    Expand
    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
      res.redirect("/");
    
    });
    
    app.get("/", (req, res) => {
      //Redirect to homepage.
      if (req.session.arcgis) {
        res.send(`
        <h1>Hi ${req.session.arcgis.username}<h1>
        <pre><code>${JSON.stringify(req.session.arcgis, null, 2)}</code></pre>
        <a href="/sign-out">Sign Out<a>
      `);
      } else {
        res.send(`<a href="/sign-in">Sign In<a>`);
      }
    });
    
    app.listen(3000, () => {
      console.log(`Visit http://localhost:3000/ to get started!`);
    });

When you click Sign in, you will be redirected back to your server. The session information including the clientId, the refreshToken, and your username will populate the page:

REST JS sample

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.

You can no longer sign into this site. Go to your ArcGIS portal or the ArcGIS Location Platform dashboard to perform management tasks.

Your ArcGIS portal

Create, manage, and access API keys and OAuth 2.0 developer credentials, hosted layers, and data services.

Your ArcGIS Location Platform dashboard

Manage billing, monitor service usage, and access additional resources.

Learn more about these changes in the What's new in Esri Developers June 2024 blog post.

Close