Skip to content

Instantly share code, notes, and snippets.

@tomwayson
Last active April 8, 2021 20:38
Show Gist options
  • Save tomwayson/230aeeeefea46e574f732639464d5cf8 to your computer and use it in GitHub Desktop.
Save tomwayson/230aeeeefea46e574f732639464d5cf8 to your computer and use it in GitHub Desktop.
Access ArcGIS Online items using OAuthentication
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta
name="viewport"
content="initial-scale=1, maximum-scale=1,user-scalable=no"
/>
<title>Access ArcGIS Online items using @esri/arcgis-rest-auth</title>
<script src="https://unpkg.com/@esri/[email protected]/dist/umd/request.umd.min.js"></script>
<script src="https://unpkg.com/@esri/[email protected]/dist/umd/auth.umd.min.js"></script>
<script src="https://unpkg.com/@esri/[email protected]/dist/umd/portal.umd.min.js"></script>
<style>
html,
body {
font-size: 14px;
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
.esri-item-gallery .esri-item-container {
float: left;
text-align: center;
padding: 10px;
width: 204px;
display: inline-block;
}
.esri-item-gallery .esri-image {
width: 200px;
height: 133px;
border: 2px solid gray;
border-radius: 5px;
}
.esri-item-gallery .esri-null-image {
line-height: 133px;
text-align: center;
color: #999999;
}
.esri-item-gallery .esri-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.esri-item-gallery .esri-null-title {
color: #999999;
}
.action {
color: blue;
cursor: pointer;
text-decoration: underline;
}
</style>
<script>
window.addEventListener('DOMContentLoaded', () => {
var personalPanelElement = document.getElementById("personalizedPanel");
var anonPanelElement = document.getElementById("anonymousPanel");
var userIdElement = document.getElementById("userId");
var info = {
// Swap this ID out with registered application ID
clientId: 'qVp7iuFvZLBFwrEQ',
redirectUri: window.location.origin + window.location.pathname + 'redirect.html',
popup: false
};
var session = checkSignInStatus();
if (session) {
displayItems();
} else {
// Anonymous view
anonPanelElement.style.display = "block";
personalPanelElement.style.display = "none";
}
document
.getElementById("sign-in")
.addEventListener("click", function() {
// user will be redirected to OAuth Sign In page
arcgisRest.UserSession.beginOAuth2(info);
});
document
.getElementById("sign-out")
.addEventListener("click", function() {
destroyCredentials();
window.location.reload();
});
function displayItems() {
userIdElement.innerHTML = session.username;
anonPanelElement.style.display = "none";
personalPanelElement.style.display = "block";
arcgisRest.searchItems({
authentication: session,
q: "owner:" + session.username,
sortField: "numViews",
sortOrder: "desc",
num: 20
}).then(createGallery);
}
function createGallery(items) {
var htmlFragment = "";
items.results.forEach(function(item) {
// NOTE: rest-js doesn't (yet) decorate the item w/ the thumbnailUrl
// see: https://github.com/Esri/arcgis-rest-js/issues/333
var thumbnailUrl = item.thumbnail && 'https://www.arcgis.com/sharing/rest/content/items/' + item.id + '/info/' + item.thumbnail + '?f=json&token=' + session.token;
htmlFragment +=
'<div class="esri-item-container">' +
(thumbnailUrl
? '<div class="esri-image" style="background-image:url(' +
thumbnailUrl +
');"></div>'
: '<div class="esri-image esri-null-image">Thumbnail not available</div>') +
(item.title
? '<div class="esri-title">' + (item.title || "") + "</div>"
: '<div class="esri-title esri-null-title">Title not available</div>') +
"</div>";
});
document.getElementById("itemGallery").innerHTML = htmlFragment;
}
// NOTE: arcgis-rest-js doesn't have opinions on how you store the OAuth credentials
// so we have to provide our own functions for how to retrieve and clear the credentials
function checkSignInStatus() {
var session;
// Check to see if there is a serialized session in local storage.
// NOTE: there is nothing special about this key,
// it just needs to match what we set in redirect.html
var serializedSession = localStorage.getItem('__ARCGIS_REST_USER_SESSION__');
if (serializedSession !== null && serializedSession !== "undefined") {
// If there is a serialized session, parse it and create a new session object.
let parsed = JSON.parse(serializedSession);
// Cast the tokenExpires property back into a date.
parsed.tokenExpires = new Date(parsed.tokenExpires);
// Create the new session object.
session = new arcgisRest.UserSession(parsed);
}
return session;
}
function destroyCredentials() {
// Clear the previous session.
localStorage.removeItem('__ARCGIS_REST_USER_SESSION__');
}
});
</script>
</head>
<body>
<div
id="anonymousPanel"
style="display: none; padding: 5px; text-align: center;"
>
<span id="sign-in" class="action">Sign In</span> and view your ArcGIS
Online items.
</div>
<div
id="personalizedPanel"
style="display: none; padding: 5px; text-align: center;"
>
Welcome <span id="userId" style="font-weight: bold;"></span> &nbsp;-&nbsp;
<span id="sign-out" class="action">Sign Out</span>
</div>
<div id="itemGallery" class="esri-item-gallery" style="width: 100%;"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<!-- arcgis-rest-js script to complete user sign in -->
<script src="https://unpkg.com/@esri/[email protected]/dist/umd/request.umd.min.js"></script>
<script src="https://unpkg.com/@esri/[email protected]/dist/umd/auth.umd.min.js"></script>
</head>
<body>
<script>
/* in a production app, clientId could be hardcoded. here we're using a regex to extract it from the state parameter in the OAuth2 server response to make the demo more interchangeable.
this relies on the fact that the ClientId is associated with the state parameter internally when another value isn't supplied manually.
*/
const match = window.location.href.match(
/&state=([^&]+)/
);
const clientId = match[1];
let session = arcgisRest.UserSession.completeOAuth2({
clientId: clientId,
});
// make the session available to the main page and redirect back there
localStorage.setItem('__ARCGIS_REST_USER_SESSION__', session.serialize());
window.location.href = './';
</script>
</body>
</html>
@tomwayson
Copy link
Author

This is a port of the Access ArcGIS Online items using OAuthentication sample that is implemented with ArcGIS REST JS instead of the ArcGIS API for JavaScript. While the the diff is interesting, what's more illustrative is checking the size of the JavaScript in the network panel:

ArcGIS API for JavaScript:

image

ArcGIS REST JS:

image

This shows why you might want to use ArcGIS REST JS initially and lazy load the ArcGIS API for JavaScript only when you need to render a map using something like esri-loader.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment