<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Implementing user authentication with Javascript API for Experience web app in ArcGIS JavaScript Maps SDK Questions</title>
    <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521542#M85353</link>
    <description>&lt;P&gt;Thank you for your answer. Unfortunately, I was unable to get either method to work. However, after adding &amp;lt;script src="&lt;A href="https://js.arcgis.com/4.29/" target="_blank"&gt;https://js.arcgis.com/4.29/&lt;/A&gt;"&amp;gt;&amp;lt;/script&amp;gt; into the body of the file, my issues seem to be resolved for now.&lt;/P&gt;</description>
    <pubDate>Wed, 14 Aug 2024 14:17:22 GMT</pubDate>
    <dc:creator>MalinEngelhardt</dc:creator>
    <dc:date>2024-08-14T14:17:22Z</dc:date>
    <item>
      <title>Implementing user authentication with Javascript API for Experience web app</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521231#M85344</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;I created an Experience with the ArcGIS Experience Builder Developer version, which is deployed on my server. Since I want users to use Analysis tools I have included in the Experience I need to implement user authentication. I want users to have a login button to then be able to view the map and use the tools in my experience.&lt;/P&gt;&lt;P&gt;I don't have much experience with authentication processes so I have not been able to include the authentication process properly into my Experience. So far I have come up with the following code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang="en-us"&amp;gt;

&amp;lt;head&amp;gt;
    &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=EDGE"/&amp;gt;
    &amp;lt;meta name="google-site-verification" content="Gl928UcZRBt8t7njrpXivrsVrbVcc7sLybtCMZ6Dzlg"/&amp;gt;
    &amp;lt;title&amp;gt;Web GIS&amp;lt;/title&amp;gt;
    &amp;lt;link rel="shortcut icon" href="assets/exb.ico"&amp;gt;
    &amp;lt;link rel="stylesheet" href="https://js.arcgis.com/4.29/esri/themes/light/main.css"&amp;gt;
	&amp;lt;base href="./cdn/4/"/&amp;gt;
	&amp;lt;script src="https://cdn.jsdelivr.net/npm/bowser@2.11.0/es5.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;style&amp;gt;
        * {
            scrollbar-color: var(--light-600) transparent;
        }
        html, body {
            width: 100%;
            height: 100%;
            margin: 0;
            overflow: hidden;
        }
        html.scrollable {
            overflow: auto;
        }
        html.scrollable body {
            overflow: unset;
        }
        html.scrollable body, html.scrollable #app {
            height: auto;
        }
        #loading {
            width: 100vw;
            height: 100vh;
        }
        #app {
            width: 100%;
            height: 100%;
            position: relative;
            z-index: 0;
            display: none;
        }
        .auth-buttons {
            position: absolute;
            top: 10px;
            right: 10px;
            z-index: 10;
        }
        .auth-buttons button {
            margin-left: 10px;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
    &amp;lt;div id="loading"&amp;gt;
        &amp;lt;style&amp;gt;
            .loading-content {
                position: absolute;
                top: 0;
                bottom: 0;
                left: 0;
                right: 0;
            }
            .jimu-primary-loading-app:before, .jimu-primary-loading-app:after {
                position: absolute;
                top: 0;
                content: '';
            }
            .jimu-primary-loading-app:before {
                left: -19.992px;
            }
            .jimu-primary-loading-app:after {
                left: 19.992px;
                -webkit-animation-delay: 0.32s !important;
                animation-delay: 0.32s !important;
            }
            .jimu-primary-loading-app:before, .jimu-primary-loading-app:after, .jimu-primary-loading-app {
                background: #076fe5;
                -webkit-animation: loading-keys-app-loading 0.8s infinite ease-in-out;
                animation: loading-keys-app-loading 0.8s infinite ease-in-out;
                width: 13.6px;
                height: 32px;
            }
            .jimu-primary-loading-app {
                text-indent: -9999em;
                margin: auto;
                position: absolute;
                right: calc(50% - 6.8px);
                top: calc(50% - 16px);
                -webkit-animation-delay: 0.16s !important;
                animation-delay: 0.16s !important;
            }
            @-webkit-keyframes loading-keys-app-loading {
                0%, 80%, 100% { opacity: .75; box-shadow: 0 0 #076fe5; height: 32px; }
                40% { opacity: 1; box-shadow: 0 -8px #076fe5; height: 40px; }
            }
            @keyframes loading-keys-app-loading {
                0%, 80%, 100% { opacity: .75; box-shadow: 0 0 #076fe5; height: 32px; }
                40% { opacity: 1; box-shadow: 0 -8px #076fe5; height: 40px; }
            }
        &amp;lt;/style&amp;gt;
        &amp;lt;div class="loading-content"&amp;gt;
            &amp;lt;div class="justify-content-center jimu-primary-loading-app"&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div id="app"&amp;gt;&amp;lt;/div&amp;gt;

    &amp;lt;div class="auth-buttons"&amp;gt;
        &amp;lt;button id="sign-in" class="btn btn-primary"&amp;gt;Sign In&amp;lt;/button&amp;gt;
        &amp;lt;button id="sign-out" class="btn btn-primary" style="display:none;"&amp;gt;Sign Out&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;pre&amp;gt;&amp;lt;code id="results"&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;

    &amp;lt;script type="webpack-options" id="webpack-options"&amp;gt;{
        "mountPath": "/",
        "isOutOfExb": true,
        "hostEnv": "prod",
        "appFolderName": ".",
        "useStructuralUrl": false,
        "arcgisJsApiUrl": "https://js.arcgis.com/4.29/",
        "isDevEdition": true,
        "buildNumber": "1",
        "isBuilder": false,
        "isSite": false,
        "isInPortal": false
    }&amp;lt;/script&amp;gt;

    &amp;lt;script type="systemjs-importmap"&amp;gt;{
        "imports": {
            "jimu-core": "https://BASE_URL/jimu-core/index.js",
            "jimu-core/": "https://BASE_URL/jimu-core/",
            "jimu-theme": "https://BASE_URL/jimu-theme/index.js",
            "jimu-theme/": "https://BASE_URL/jimu-theme/",
            "jimu-ui": "https://BASE_URL/jimu-ui/index.js",
            "jimu-ui/": "https://BASE_URL/jimu-ui/",
            "jimu-icons/": "https://BASE_URL/jimu-icons/",
            "jimu-arcgis": "https://BASE_URL/jimu-arcgis/index.js",
            "jimu-arcgis/": "https://BASE_URL/jimu-arcgis/",
            "jimu-layouts": "https://BASE_URL/jimu-layouts/index.js",
            "jimu-layouts/": "https://BASE_URL/jimu-layouts/",
            "jimu-for-builder": "https://BASE_URL/jimu-for-builder/index.js",
            "jimu-for-builder/": "https://BASE_URL/jimu-for-builder/",
            "widgets/": "https://BASE_URL/widgets/",
            "themes/": "https://BASE_URL/themes/",
            "builder/": "https://BASE_URL/builder/",
            "site/": "https://BASE_URL/site/",
            "experience/": "https://BASE_URL/experience/",
            "template/": "https://BASE_URL/template/",
            "templates/": "https://BASE_URL/templates/",
            "calcite-components": "https://BASE_URL/calcite-components/index.js",
            "calcite-components/": "https://BASE_URL/calcite-components/",
            "arcgis-charts": "https://BASE_URL/arcgis-charts/arcgis-charts.js",
            "arcgis-amd-packages/": "https://amd-packages/",
            "esri/": "https://API_URL/esri/"
        }
    }&amp;lt;/script&amp;gt;

    &amp;lt;script src="./jimu-core/init.js"&amp;gt;&amp;lt;/script&amp;gt;

    &amp;lt;!-- Authentication script --&amp;gt;
    &amp;lt;script&amp;gt;
        require([
            "esri/portal/Portal",
            "esri/identity/OAuthInfo",
            "esri/identity/IdentityManager"
        ], function (Portal, OAuthInfo, esriId) {

            const info = new OAuthInfo({
                appId: "My-APP-ID", // removed due to privacy reasons
                popup: false // Use false if you want to redirect instead of using a popup
            });
            esriId.registerOAuthInfos([info]);

            esriId.checkSignInStatus(info.portalUrl + "/sharing")
                .then(() =&amp;gt; {
                    handleSignedIn();
                })
                .catch(() =&amp;gt; {
                    handleSignedOut();
                });

            document.getElementById("sign-in").addEventListener("click", function () {
                esriId.getCredential(info.portalUrl + "/sharing");
            });

            document.getElementById("sign-out").addEventListener("click", function () {
                esriId.destroyCredentials();
                window.location.reload();
            });

            function handleSignedIn() {
                const portal = new Portal();
                portal.load().then(() =&amp;gt; {
                    const results = {
                        name: portal.user.fullName,
                        username: portal.user.username
                    };
                    document.getElementById("results").innerText = JSON.stringify(results, null, 2);
                    document.getElementById("sign-in").style.display = "none";
                    document.getElementById("sign-out").style.display = "block";
                });
            }

            function handleSignedOut() {
                document.getElementById("results").innerText = 'Signed Out';
                document.getElementById("sign-in").style.display = "block";
                document.getElementById("sign-out").style.display = "none";
            }
        });
    &amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This will load my Experience and display a button, but I can't log in due to a ReferenceError: require is not defined. Adding &amp;lt;script src="&lt;A href="https://js.arcgis.com/4.29/" target="_blank"&gt;https://js.arcgis.com/4.29/&lt;/A&gt;"&amp;gt;&amp;lt;/script&amp;gt; in the header will result in a MultipleDefines Error instead.&lt;/P&gt;&lt;P&gt;Any help would be appreciated.&lt;/P&gt;</description>
      <pubDate>Wed, 14 Aug 2024 08:22:30 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521231#M85344</guid>
      <dc:creator>MalinEngelhardt</dc:creator>
      <dc:date>2024-08-14T08:22:30Z</dc:date>
    </item>
    <item>
      <title>Re: Implementing user authentication with Javascript API for Experience web app</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521399#M85345</link>
      <description>&lt;P&gt;Hey &lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/742000"&gt;@MalinEngelhardt&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The MutipleDefines appears that it comes from the link that you're adding into the header, as require is defined many times.&lt;/P&gt;&lt;P&gt;Instead of require, you could use the System.import method to attempt and load the information in:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;System.import('esri/portal/Portal').then(function (Portal) {
    System.import('esri/identity/OAuthInfo').then(function (OAuthInfo) {
        System.import('esri/identity/IdentityManager').then(function (esriId) {&lt;/LI-CODE&gt;&lt;P&gt;If this doesn't end up working, you could attempt to import the functions at the top of your script, as in standard JS.&lt;/P&gt;&lt;P&gt;import &amp;lt;Portal&amp;gt; from &amp;lt;esri/portal/Portal&amp;gt;&lt;/P&gt;&lt;P&gt;And so on.&lt;/P&gt;&lt;P&gt;Hope that helps!&lt;/P&gt;&lt;P&gt;Cody&lt;/P&gt;</description>
      <pubDate>Wed, 14 Aug 2024 11:36:52 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521399#M85345</guid>
      <dc:creator>CodyPatterson</dc:creator>
      <dc:date>2024-08-14T11:36:52Z</dc:date>
    </item>
    <item>
      <title>Re: Implementing user authentication with Javascript API for Experience web app</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521503#M85349</link>
      <description>&lt;P&gt;In my custom widget that I am current working on (so I don't have everything in place, such as the settings panel), I have a button to authenticate and return a specific layer that is shared with the user.&lt;/P&gt;&lt;P&gt;It's a separate component from the main widget, which is imported and used like this:&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;...
import SignIn from '../components/SignIn';
...

return (
  ...
    &amp;lt;SignIn getUrl={getUrl} {...props}&amp;gt;&amp;lt;/SignIn&amp;gt; //getUrl is a function that uses the url in the component to make a feature layer and add it to the map.&lt;/LI-CODE&gt;&lt;P&gt;This is the SignIn component. Since I haven't worked on the settings panel, I use tempConfig in its place.&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;import { AllWidgetProps } from 'jimu-core';
import { Alert, Button } from 'jimu-ui';
import React, { useState } from 'react';
import OAuthInfo from '@arcgis/core/identity/OAuthInfo';
import esriId from '@arcgis/core/identity/IdentityManager';
import esriConfig from '@arcgis/core/config';
import Portal from '@arcgis/core/portal/Portal';
import PortalQueryParams from '@arcgis/core/portal/PortalQueryParams';
import tempconfig from '../assets/test_config.json';
import { IMConfig } from '../config';
import FeatureLayer from '@arcgis/core/layers/FeatureLayer';

export default function SignIn({ getUrl }, props: AllWidgetProps&amp;lt;IMConfig&amp;gt;) {
  const [buttonText, setButtonText] = useState('Sign In');
  const [signedIn, setSignedIn] = useState(false);
  const [welcomeText, setWelcomeText] = useState('');
  const [showAlert, setShowAlert] = useState(false);
  const [alertMessage, setAlertMessage] = useState('');

  let gridUrl: string = null;
  let _portal: Portal;
  let _ownerName: string = tempconfig.agolSettings.ownerName;
  let _baseGridLayerName: string = tempconfig.agolSettings.baseGrid;
  const portalUrl = tempconfig.agolSettings.portalUrl; //your portal
  const appInfo = tempconfig.agolSettings.auths;  //see below
  let theAppId: string, thePopupCallbackUrl: string;

  //functions

  const formSubmit = () =&amp;gt; {
    if (signedIn) {
      logOff();
    } else {
      logOn();
    }
  };

  const logOn = () =&amp;gt; {
    setSignedIn(true);
    setButtonText('Sign Out');
    setShowAlert(false);
    const loc = window.location.hostname;
    const location = appInfo.find(
      (x) =&amp;gt; x.location === window.location.hostname
    );
    if (location !== undefined) {
      theAppId = location.appId;
      thePopupCallbackUrl = location.popupCallbackUrl;
    } else {
      setAlertMessage(
        `This site (${window.location.hostname}) is not in the Authentication Location table in the Settings.`
      );
      setShowAlert(true);
      logOff();
      return;
    }

    const info = new OAuthInfo({
      appId: theAppId,
      flowType: 'auto',
      popup: false,
    });
    esriConfig.request.trustedServers.push(portalUrl);
    esriId.registerOAuthInfos([info]);
    try {
      esriId
        .getCredential(info.portalUrl, { oAuthPopupConfirmation: false })
        .then(() =&amp;gt; {
          _portal = new Portal({ url: portalUrl });

          _portal.load().then(() =&amp;gt; {
            const queryParams: PortalQueryParams = {
              num: 100,
              query: `owner: ${_ownerName} AND type: "Feature Service" AND title: "${_baseGridLayerName}"`, //this finds the specific layer in AGOL
              sortField: 'title',
              sortOrder: 'asc',
            };
            _portal.queryItems(queryParams).then((results) =&amp;gt; {
              if (results.total == 0) {
                setAlertMessage('The layer is not available');
                setShowAlert(true);
                logOff();
                return;
              }
              if (
                !results.results.some((item) =&amp;gt; {
                  if (item.url == null) return false;
                  gridUrl = item.url;
                  return item.url.indexOf(_baseGridLayerName) &amp;gt; -1;
                })
              ) {
                setAlertMessage(
                  'You are not authorized to use this layer!'
                );
                setShowAlert(true);
                logOff();
                return;
              }
              setWelcomeText(`Welcome ${_portal.user.fullName}`);
              getUrl(gridUrl);
            });
          });
        });
    } catch ({ name, message }) {
      console.log(`***********${name}`);
      console.log(message);
    }
  };

  const logOff = () =&amp;gt; {
    setSignedIn(false);
    setWelcomeText('');
    setButtonText('Sign In');
    esriId.destroyCredentials();
    getUrl('');;
  };

  const styles = {
    wrapper: {
      display: 'flex',
      margin: '10px',
      alignItems: 'center',
      justifyContent: 'space-between',
    },
    welcome: {
      marginLeft: 'auto',
    },
    alert: {
      margin: '10px',
      width: 'auto',
    },
  };
  return (
    &amp;lt;&amp;gt;
      &amp;lt;div className="wrapper" style={styles.wrapper}&amp;gt;
        {/* &amp;lt;form onSubmit={formSubmit}&amp;gt; */}
        &amp;lt;Button onClick={formSubmit}&amp;gt;{buttonText}&amp;lt;/Button&amp;gt;
        &amp;lt;div className="text" style={styles.welcome}&amp;gt;
          {welcomeText}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;Alert
        style={styles.alert}
        text={alertMessage}
        type="error"
        open={showAlert}
      /&amp;gt;
    &amp;lt;/&amp;gt;
  );
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;On Line 25, appInfo is an array of possible locations where the user is signing in from, along with the appId set up for that location. That looks like this:&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;  "auths": [
    {
      "location": "localhost",
      "appId": "xxxxxxxxxxxxxxxx"
    },
    {
      "location": "development server url",
      "appId": "yyyyyyyyyyyyyyyy"
    },
    {
      "location": "production server url",
      "appId": "zzzzzzzzzzzzzzzz"
    }&lt;/LI-CODE&gt;</description>
      <pubDate>Wed, 14 Aug 2024 13:39:04 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521503#M85349</guid>
      <dc:creator>KenBuja</dc:creator>
      <dc:date>2024-08-14T13:39:04Z</dc:date>
    </item>
    <item>
      <title>Re: Implementing user authentication with Javascript API for Experience web app</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521513#M85350</link>
      <description>&lt;P&gt;Since I can't current edit my own post, please note that "auths" looks like this&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;  "auths": [
    {
      "location": "localhost",
      "appId": "xxxxxxxxxxxxxxxx",
      "popupCallbackUrl": "../assets/oauth-callback.html"
    },
    {
      "location": "development server url",
      "appId": "yyyyyyyyyyyyyyyy",
      "popupCallbackUrl": "../assets/oauth-callback.html"
    },
    {
      "location": "production server url",
      "appId": "zzzzzzzzzzzzzzzz",
      "popupCallbackUrl": "../assets/oauth-callback.html"
    }&lt;/LI-CODE&gt;</description>
      <pubDate>Wed, 14 Aug 2024 13:55:33 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521513#M85350</guid>
      <dc:creator>KenBuja</dc:creator>
      <dc:date>2024-08-14T13:55:33Z</dc:date>
    </item>
    <item>
      <title>Re: Implementing user authentication with Javascript API for Experience web app</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521542#M85353</link>
      <description>&lt;P&gt;Thank you for your answer. Unfortunately, I was unable to get either method to work. However, after adding &amp;lt;script src="&lt;A href="https://js.arcgis.com/4.29/" target="_blank"&gt;https://js.arcgis.com/4.29/&lt;/A&gt;"&amp;gt;&amp;lt;/script&amp;gt; into the body of the file, my issues seem to be resolved for now.&lt;/P&gt;</description>
      <pubDate>Wed, 14 Aug 2024 14:17:22 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521542#M85353</guid>
      <dc:creator>MalinEngelhardt</dc:creator>
      <dc:date>2024-08-14T14:17:22Z</dc:date>
    </item>
    <item>
      <title>Re: Implementing user authentication with Javascript API for Experience web app</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521544#M85354</link>
      <description>&lt;P&gt;Thank you for your answer. While I have resolved my issue, moving the login into a custom widget will be something I will look into.&lt;/P&gt;</description>
      <pubDate>Wed, 14 Aug 2024 14:20:40 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/implementing-user-authentication-with-javascript/m-p/1521544#M85354</guid>
      <dc:creator>MalinEngelhardt</dc:creator>
      <dc:date>2024-08-14T14:20:40Z</dc:date>
    </item>
  </channel>
</rss>

