Authenticate with an ArcGIS identity (server)
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.
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
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. To learn more, refer to the Register your application tutorial.
Update your registered application to specify the Redirect URLs to use for authentication, in the format
"https://<server>[:port]"
orhttp://my-arcgis-app:/auth
. For example, this tutorial useshttp://localhost:3000/authenticate
, so you will need to add that URL to your list of redirect URLs.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.
Steps
Set up a configuration file
In your developer dashboard, get your client ID. Ensure that
http//localhost:3000/authenticate
is registered for your application.Open a code editor and create a
config.json
file. Set theCLIENT_ID
andREDIRECT_URI
to those configured for your application in your developer dashboard. Set secure strings for the theSESSION_SECRET
and theENCRYPTION_KEY
. These can be generated at RandomKeygen.config.jsonUse dark colors for code blocks Add line. Add line. Add line. Add line. Add line. Add line. 1 2 3 4 5 6
{ "CLIENT_ID": "CLIENT_ID", "SESSION_SECRET": "SESSION_SECRET", "ENCRYPTION_KEY": "ENCRYPTION_KEY", "REDIRECT_URI": "http://localhost:3000/authenticate" }
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.
In a separate
server.js
file, import theexpress
,express-session
, andsession-file-store
npm packages, as well as the ArcGIS REST JSArcGISIdentityManager
class.server.jsUse dark colors for code blocks 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });Create an instance of
express
and acredentials
object to set theclientId
andredirectUri
.server.jsUse dark colors for code blocks 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });
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.
Call the
authorize
method withcredentials
andres
(the response object) as parameters when the user gets redirected to the sign in page.server.jsUse 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });Destroy
the cookie and session file when the user signs out and returns to the home page.server.jsUse dark colors for code blocks 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });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.jsUse 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });Redirect the user to the home page and display session information when the user provides credentials.
server.jsUse 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. 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });
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.
Save the sesssion on the user's machine and redirect the user to the homepage.
server.jsUse dark colors for code blocks 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });Call the
use
method ofexpress
to start implementingexpress-session
. Set thesecret
to your application'sSESSION_SECRET
. This is used to encrypt the cookies and session information.express-session
supports many different kinds of compatible stores. For a list of stores, see [compatible session stores(https://www.npmjs.com/package/express-session#compatible-session-stores).server.jsUse 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. 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });Create a
FileStore
to save the sessions on your server as files., and set thesecret
with theENCRYPTION_KEY
you configured in theconfig.json
file.server.jsUse dark colors for code blocks 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });Set the
encoder
option with thesessionObj
to serialize the session object before it is encrypted and stored on disk. Thedecoder
decodes thesessionContent
using the encryption key the user specifies.server.jsUse 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });Set the
decode
option to deserialize thesessionObj
into a JavaScript object.server.jsUse dark colors for code blocks 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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!`); });
Run the app
Call the
listen
method and place aconsole.log
to allow the user to navigate tohttp://localhost:3000/
.server.jsUse 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
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"); const { CLIENT_ID, SESSION_SECRET, ENCRYPTION_KEY, REDIRECT_URI } = require("./config.json"); const credentials = { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }; 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; } }) }) ); app.get("/sign-in", (req, res) => { ArcGISIdentityManager.authorize(credentials, res); }); app.get("/sign-out", (req, res) => { // invalidate the token req.session.arcgis.destroy().then(() => { // delete the cookie and stored session req.session.destroy(); res.redirect("/"); }); }); app.get("/authenticate", async (req, res) => { req.session.arcgis = await ArcGISIdentityManager.exchangeAuthorizationCode( { clientId: CLIENT_ID, redirectUri: REDIRECT_URI }, req.query.code //The code from the redirect: exchange code for a token in instaniated user session. ); 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:
What's next?
Learn how to use additional ArcGIS location services in these tutorials:
Edit feature data
Add, update, and delete data in a hosted feature layer.