ArcGIS Server Token with VectorTileLayer

1332
4
10-12-2021 04:45 AM
MirHashmi
Occasional Contributor

Is there a way to access secured service through VectorTileLayer in ArcGIS JS API.  I have tried with using methods - interceptor and  CustomParameters - but nothing seems to work. Am I missing something? 

1. Generated token
2. Tried to append token in interceptor and customparameters


      // esriConfig.request.interceptors.push({
      //   urls: myBaseMapUrl,
      //   before: function(params) {
      //     params.requestOptions.query = params.requestOptions.query || {};
      //     params.requestOptions.query.token = this.accesstoken;
      //   }
      // });

      // My Basemap vector tile layer
      const myBaseMapLayers = new VectorTileLayer({
          url: (prd) ? myBaseMapUrl : oLBaseMapUrl,
          customParameters: {
            "token": this.accesstoken
          }
      });
 
My application always presents me with the credentials dialog box and I do not need it.
 

@ReneRubalcava 

Thanks

0 Kudos
4 Replies
UndralBatsukh
Esri Regular Contributor

Hi there, 

The customParameters is not supported on VectorTileLayer so setting it on the layer won't help. However, the before interceptors will work. If you are being asked to login that means you still have urls that need to have the token attached. You can look in the network tab to see where it's being sent and which response says it needs a token. Copy those urls and add them to the interceptor urls. Your vector tiles will display without a login promo, once all urls requiring tokens are added to the interceptor urls. I have tested and verified that it works as expected. 

Here is my simple test (token is already expired in this case) and I am adding vector tiles from a protected portal item however the service itself is publicly accessible (so I don't have to add urls for the service). 

  const interceptor = {
          urls: [
            "https://www.arcgis.com/sharing/rest/content/items/92499d146008498091eed0ffaa4b09d5"
          ],
          before({ url, requestOptions }) {
            requestOptions.query.token = "10ilTU8DrsMBMrmj2kApv1pkhFn0MS1OhjNoAzFWU7DUeQufPC9xNj-4lDd0Di1MTSHzwzPKwDdDiE1gDRcXTAxWsFVyCbVoFsChB_9Ez1C6NSqkRE3mftygP_2zW3KEDrmRw87zcwFxezZ9Q9SW0AxlxOeVAZf1o0G5wSwvF11J8jRovtfqunLunkjXQiFFViTKgnDM5NbOc7TAU5uyUes3piH5FCWxts36StJUMAw.";
          }
        };

        esriConfig.request.interceptors.push(interceptor);
        const map = new Map();

        // Make map view and bind it to the map
        const view = new MapView({
          container: "viewDiv",
          map: map,
          center: [-98.5795, 39.8282],
          zoom: 3
        });

        const tileLayer = new VectorTileLayer({
          portalItem: {
            id: "92499d146008498091eed0ffaa4b09d5"
          }
        });
        map.add(tileLayer);

 

Hope this helps,

-Undral

MirHashmi
Occasional Contributor

Hi @UndralBatsukh Thanks for your reply. I've tried to implement a test page that works but it still doesnt draw the map. Here is the code and a link to jsfiddle.  Looking at the dev tools network tab, I can see that it loads required urls with the token but still map doesn't draw.  Am I missing something here?

 

<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>VectorTileLayer | Sample | ArcGIS API for JavaScript 4.21</title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.21/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.21/"></script>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/VectorTileLayer",
        "esri/config"
      ], (Map, MapView, VectorTileLayer, esriConfig) => {
        // Create a Map
        const map = new Map();

        // Make map view and bind it to the map
        const view = new MapView({
          container: "viewDiv",
          map: map,
          center: [46.897998, 24.598897],
          zoom: 5
        });

        /********************************************************************
         * Add a vector tile layer to the map
         *
         * The url must point to the style or the vector tile service
         *********************************************************************/
        const tileLayer = new VectorTileLayer({
          url: "https://abc.ab.ca/server/rest/services/Hosted/MyMapService/VectorTileServer"
        });

        const interceptor = {
          urls: tileLayer.url,
          before: function (params) {
            params.requestOptions.query.token =
              "Xj9OUDvMFYz3BHd3fcPnHiJdmmae9gWrfT4WL-VFmJjwoeu82JSC4SCzPc18a7Z_c0VaS-xdFD3neOCtAhn0rKIXaSE7ilsN7Z4F0xTclcGYsDNI-E1UyKtL5YmSkgphSRlwfsrAOU9rEqzu4Z_LDo9b6XFUCi00S5glYTv28pE.";
          }
        };

        esriConfig.request.interceptors.push(interceptor);

        map.add(tileLayer);
      });
    </script>
  </head>
  <body>
    <div id="viewDiv"></div>
  </body>
</html>

 

 

 

 

 

0 Kudos
SailiTang1
New Contributor III

Hi,

Did you try this? Adding the service to ArcGIS online and turning on "Store Credentials with service item. Do not prompt for authentication." And then, share the item you added to public.

SailiTang1_0-1634061244985.png

 

0 Kudos
MirHashmi
Occasional Contributor

Hi @SailiTang1  Thanks for your reply. However, I do not have an ArcGIS online option available. The service is available on premises arcgis portal. Thanks.

0 Kudos