Note This is a new api feature, and currently there are no platform applications that support the authentication flows discussed in this guide. However, this guide exists to help other platform app teams add this functionality to their apps.
Authentication with Embedded ApplicationsSometimes an application will need to embed another application using an <iframe>
. If both applications are backed by items that are publicly accessible, things will "just work".
However, if the embedded application is not public and the user has already logged into the "Host" application, we then run into the question of how to pass authentication from the "Host" to the embedded application.
Message Types and ObjectsAlthough this is internalized within the functions, the message types and the objects are documented in the repo in the postMessage Auth Spec document
Cross Origin EmbeddingCross-Origin embedding occurs when the "host" app and the "embedded" application are served from different locations. This is only supported for ArcGIS Platform apps that support embedding.
For example, you can build a custom app, hosted at http://myapp.com
and iframe in a "platform app" that supports embedding. However, you can not embed your custom app into a StoryMap, and expect the StoryMap to pass authentication to your app. This is done for security reasons.
postMessage
The browser's postMessage
api is designed to allow communication between various "frames" in a page, and it is how this works internally. You can read more about postMessage at the Mozilla Developer Network.
We will walk through the flows at a high-level
1 Host App uses oAuthThe application acting as the host, should use oAuth to authenticate the user, and before rendering the iframe with the embedded application it must call session.enablePostMessageAuth(validOrigins)
. This sets up a listener that will process the requests from the embedded application(s).
The validOrigins
argument is an array of "origins" your app expects to get auth requests from. NOTE This should be a constrained list of just the domains this particular application will actually be embedding.
const clientId = "abc123";
UserSession.beginOAuth2({
clientId,
redirectUri: "https://yourapp.com/authenticate.html",
}).then((session) => {
const validOrigins = ["https://storymaps.arcgis.com"];
session.enablePostMessageAuth(validOrigins);
});
2 Host App adds params to embed url
Let's suppose the host app is embedding https://storymaps.arcgis.com/stories/15a9b9991fff47ad84f4618a28b01afd
. To tell the embedded app that it should request authentication from the parent, we need to add two url parameters:
arcgis-auth-origin=https://myapp.com
- This tells the app it's embedded in an iframe and should request auth from the parent, and what 'origin' to expect messages from, what origin to post messages to, and also to ignore other origins.arcgis-auth-portal=https://www.arcgis.com/sharing/rest
- This tells the embedded app the ArcGIS Portal that the parent will provide authentication for.
encodeURIComponent()
as shown belowconst originalUrl =
"https://storymaps.arcgis.com/stories/15a9b9991fff47ad84f4618a28b01afd";
const embedUrl = `${originalUrl}
?arcgis-auth-origin=${encodeURIComponent(window.location.origin)}
&arcgis-auth-portal=${encodeURIComponent(session.portal)}`;
3 Embed App boots and Requests Auth
In the embedded application, early in its boot sequence it should read the query string parameters and make the determination that it is running inside an iframe, and that it can request authentication information from the parent.
let params = new URLSearchParams(document.location.search.substring(1));
const arcgisAuthOrigin = params.get("arcgis-auth-origin");
if (arcgisAuthOrigin) {
UserSession.fromParent(arcgisAuthOrigin)
.then((session) => {
})
.catch((ex) => {
});
}
Clean up
While rest-js will attempt to clean up the listeners automatically, if the host application is no longer going to render the iframe before the embedded app has had a chance to request the authentication, then the app should manually clean up the listener by calling session.disablePostMessageAuth()
Typically you would make this call in the life-cycle hooks of your application framework (i.e. an Angular, Ember, React etc app with a router). The example below uses the disconnectedCallback
that is part of the Stencil.js component life-cycle.
disconnectedCallback () {
state.session.disablePostMessageAuth();
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4