Esri / arcgis-rest-js

compact, modular JavaScript wrappers for the ArcGIS REST API
https://developers.arcgis.com/arcgis-rest-js/
Apache License 2.0
347 stars 119 forks source link

Embedded content workflow doesn't seem to work anymore #1156

Closed fspataro closed 2 months ago

fspataro commented 4 months ago

Describe the bug

Hi, It's likely this workflow is not supported anymore but wanted to check since the enablePostMessageAuth method is still there, maybe i'm doing something wrong with the migration to the latest version.

I'm trying to follow this guide from v2 on the latest version: https://esri.github.io/arcgis-rest-js/guides/embedded-apps/

I've taken browser-oauth sample from here: https://developers.arcgis.com/arcgis-rest-js/authentication/tutorials/implement-user-authentication-rest-js-browser/

Add the parts from the guide.

If I use a storymap, the iframe appears to try to load the normal arcgis login page and i get a 'Refused to connect'. If I use a dashboard, sometimes i get the loading spinner, and if I right-mouse-reload frame, the dashboard will load but i get the 'You don't have access to this item' message. Which is odd b/c the dev-tools network trace, shows a REST request to the item with a token and the item json is returned.

Reproduction

Modified index.html from the sample... clientid removed... urls are from my agol org for reference.

<!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 class="row">
          <div class="col-xs-12">
            <div id="viewDiv" style="padding: 0; margin: 0; height: 1000px; background: lightslategrey; border: 10px solid black;"></div>
          </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 = "123";
      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);
        updateIFrame(session);
      }

      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);

      function updateIFrame(session) {
                const validOrigins = ["https://gcs.maps.arcgis.com","https://storymaps.arcgis.com"];
                session.enablePostMessageAuth(validOrigins);

                //const originalUrl = "https://gcs.maps.arcgis.com/apps/dashboards/f0898e78bdad4c98a435b30e5bb58b71";
                const originalUrl = "https://storymaps.arcgis.com/stories/a2b87928390c46f9b9ed1c59c885c15f"; const embedUrl = `${originalUrl}?arcgis-auth-origin=${encodeURIComponent(window.location.origin)}&arcgis-auth-portal=${encodeURIComponent(session.portal)}`;
                console.log(embedUrl)

                document.getElementById("viewDiv").innerHTML += `<iframe id="item_ifrm" style="height:100%;width:100%" src="${embedUrl}"></iframe>`;
                document.getElementById('item_ifrm').contentDocument.defaultView.location.reload();
      }

      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);
                        updateIFrame(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.disablePostMessageAuth();
          document.getElementById("viewDiv").innerHTML = "";
          session = null; // Clear the session from memory.
          localStorage.removeItem("__ARCGIS_REST_USER_SESSION__");
          updateSessionInfo();
        });
      });

    </script>

  </body>
</html>

Logs

No response

System Info

v4.0.0 from the cdn from the example ...

Additional Information

No response

dbouwman commented 2 months ago

@fspataro the post message style auth is only supported for esri hosted applications. Sorry that the old docs suggest otherwise.

fspataro commented 2 months ago

@dbouwman thanks for following up. Question, what do you mean by 'only support for esri hosted applications'? Can you give me an example of when this approach is supported? Thanks