How do I add a secured feature service using a token in 4.X?

2938
17
Jump to solution
03-25-2021 04:15 PM
MattStayner
Occasional Contributor

I need to load a secured layer using an Esri token. In 3.X I did this:

const url = `${serviceUrl}?token=${esriToken}&f=json`
var featureLayer = new FeatureLayer({
  url: url
});

It worked great and would load the secure feature service.

I do the exact same thing in 4.X, and I get the pop-up asking me to sign in. I double-checked the URL, and it provides the JSON, so that's not the issue.

What gives? I already signed in using OAuth2. That's how I got the token. I don't want to have to sign in again. Please help. Thanks!

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
ReneRubalcava
Frequent Contributor II

We strip any URL parameters added to a layer URL to better manage params we need to use for queries and stuff. This is by design. The preferred way is IdentityManager for tokens, but you can use the requestInterceptors for this.

 

      esriConfig.request.interceptors.push({
        // set the `urls` property to the URL of the FeatureLayer so that this
        // interceptor only applies to requests made to the FeatureLayer URL
        urls: "https://services6.arcgis.com/ExtdhXSbhHKK7FFW/arcgis/rest/services/Related_Table_2/FeatureServer/0",
        // use the BeforeInterceptorCallback to add token to query
        before: function(params) {
          params.requestOptions.query = params.requestOptions.query || {};
          params.requestOptions.query.token = "my-token";
        },
      });

 

You can double check that its appended by checking the network request.

ReneRubalcava_0-1616788367716.png

Hope that helps.

 

View solution in original post

17 Replies
ReneRubalcava
Frequent Contributor II

There are a couple of options, but if you simply want to append it to the URL, you can use the before() requestInterceptor

https://developers.arcgis.com/javascript/latest/api-reference/esri-config.html#RequestInterceptor

0 Kudos
MattStayner
Occasional Contributor

Hi @ReneRubalcava ,

Thanks for the quick response? Yes, I just want to append the token to the URL. Why do I need to use a `requstInterceptor`. Why can't I just append the token to the request as shown in this example? I didn't include the actual token, but you get the idea.

At any rate, that approach doesn't work. I tried looking at before() and I can't wrap my mind around how I would do that. Would you mind updating the example to show how that would work?

0 Kudos
ReneRubalcava
Frequent Contributor II

We strip any URL parameters added to a layer URL to better manage params we need to use for queries and stuff. This is by design. The preferred way is IdentityManager for tokens, but you can use the requestInterceptors for this.

 

      esriConfig.request.interceptors.push({
        // set the `urls` property to the URL of the FeatureLayer so that this
        // interceptor only applies to requests made to the FeatureLayer URL
        urls: "https://services6.arcgis.com/ExtdhXSbhHKK7FFW/arcgis/rest/services/Related_Table_2/FeatureServer/0",
        // use the BeforeInterceptorCallback to add token to query
        before: function(params) {
          params.requestOptions.query = params.requestOptions.query || {};
          params.requestOptions.query.token = "my-token";
        },
      });

 

You can double check that its appended by checking the network request.

ReneRubalcava_0-1616788367716.png

Hope that helps.

 

MattStayner
Occasional Contributor

This worked perfectly for me. Thanks @ReneRubalcava !

0 Kudos
jaykapalczynski
Frequent Contributor

Are there parameters for Editing? I see your example shows Query Parameters but what about if I need to edit this?

0 Kudos
ShmuelKatorzaDAO
New Contributor II

Hi , 

I needed also to change in the security option the support for two options:

"allowHttpPostQueryParams"

"allowHttpGet"

 

under arcgis server admin -- > security --> tokens 

0 Kudos
ZohaibUddinKhan
New Contributor II

@ReneRubalcava Thanks for the reply. I used the same code as provide by you and replace the following:-

Now, my code looks like following:-

 

const featureLayerUrl = "https://services.slip.wa.gov.au/arcgis/rest/services/Landgate_v2_Subscription_Services/Cadastral/MapServer/35";

esriConfig.request.interceptors.push({
urls: featureLayerUrl,
before: function (params) {
params.requestOptions.query = params.requestOptions.query || {};
params.requestOptions.query.token = "nXKRnEHxxxxxxxxxxxxxxxXXXXxxxxxxxxxxxxxxx.";
},
});

const cadastreLayer = new FeatureLayer({
url: featureLayerUrl,
outfields: ["land_id"]
});

map.add(cadastreLayer);

 

But, it is still asking for the Username / Password on the page. Do you know what I'm missing? Thanks.

ReneRubalcava
Frequent Contributor II

There is probably a request being made to the root of the service to check for capabilities. You can make the request interceptor url to the root of the server.

{
  urls: "https://services.slip.wa.gov.au"
}
ZohaibUddinKhan
New Contributor II

Thanks @ReneRubalcava for the reply. I tried the change but no luck! Any clue what I'm doing wrong? I've created a separate post so that we can keep track and accept the solution later. (New post url: https://community.esri.com/t5/arcgis-api-for-javascript/how-to-access-secured-arcgis-server-map-serv...)

Following is my code for JS API v4.16:-

 

<script type="text/javascript">
        require([
            "esri/config",
            "esri/Basemap",
            "esri/Map",
            "esri/views/MapView",
            "esri/layers/VectorTileLayer",
            "esri/layers/FeatureLayer",
            "dojo/domReady!"
        ], function (esriConfig, Basemap, Map, MapView, VectorTileLayer, FeatureLayer
        ) {
            var initialLatitude = '-31.954594';
            var initialLongitude = '115.860299';
            var initialPoint = { type: "point", latitude: initialLatitude, longitude: initialLongitude };
            var vectorTileLayerID = '07a6b122323b4exxxxxxxc0a97b29';

            var wp_VectorTileLayer = new VectorTileLayer({
                portalItem: {
                    id: vectorTileLayerID
                }
            });

            var MDSbaseMap = new Basemap({
                baseLayers: [
                    wp_VectorTileLayer
                ]
            });

            var map = new Map({
                basemap: MDSbaseMap
            });

            var view = new MapView({
                container: "viewDiv",
                map: map,
                zoom: 11,
                constraints: {
                    minScale: 3000,  
                    maxScale: 30,  
                    rotationEnabled: false
                },
                center: initialPoint
            });

            view.popup.autoOpenEnabled = false;

            const featureLayerUrl = "https://services.slip.wa.gov.au/arcgis/rest/services/Landgate_v2_Subscription_Services/Cadastral/MapServer/41";
            //const featureLayerUrl = "https://token.slip.wa.gov.au/arcgis/rest/services/Landgate_v2_Subscription_Services/Cadastral/MapServer/41";

                esriConfig.request.interceptors.push({
                    urls: "https://services.slip.wa.gov.au/",
                    before: function (params) {
                        params.requestOptions.query = params.requestOptions.query || {};
                        params.requestOptions.query.token = "nXKRnEHxOLrxxxxxxxxxxxxxxtU4amjZzsrI.";//Get the token from https://token.slip.wa.gov.au/arcgis/tokens/
                    },
                });

            const layer = new FeatureLayer({
                url: featureLayerUrl
            });

            map.add(layer);

            view.ui.move(["zoom"], "bottom-left");

        });
    </script>

 

 

0 Kudos