From a3a4d74407ed875fe8d27caccfdb8dcc73161f5f Mon Sep 17 00:00:00 2001 From: Luis Camacho Date: Mon, 5 Oct 2020 02:15:32 +0100 Subject: [PATCH] Support 'withCredentials' option which will include credentials with CORS requests (#1233) * Add support for 'withCredentials' option when sending cross origin requests to servers that are secured with IWA/AD it is necessary to send request with 'withCredentials' set to true If the layer is created using this option the requests will be adjusted accordingly * added tests for 'withCredentials' option * Apply suggestions from code review adjust styling for consistency Co-authored-by: Patrick Arlt Co-authored-by: Patrick Arlt --- spec/Layers/RasterLayerSpec.js | 8 ++++++++ spec/RequestSpec.js | 18 ++++++++++++++++++ src/Layers/RasterLayer.js | 2 +- src/Request.js | 6 ++++++ src/Util.js | 2 +- 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/spec/Layers/RasterLayerSpec.js b/spec/Layers/RasterLayerSpec.js index 5fa2a568a..7570a849c 100644 --- a/spec/Layers/RasterLayerSpec.js +++ b/spec/Layers/RasterLayerSpec.js @@ -10,6 +10,7 @@ describe('L.esri.RasterLayer', function () { // Extend 'abstract' RasterLayer object and implement functionality required for tests var TestRasterLayer = L.esri.RasterLayer.extend({ initialize: function (options) { + L.setOptions(this, options); this.service = { metadata: function () {} }; @@ -91,6 +92,13 @@ describe('L.esri.RasterLayer', function () { expect(imageOverlay.off.calledWith('error', sinon.match.func, layer)).to.be.true; }); + + it('should send credentials', function () { + var layer = new TestRasterLayer({withCredentials: true}); + layer.addTo(map); + var imageOverlay = map.addLayer.getCall(1).args[0]; + expect(imageOverlay._image.crossOrigin).to.be.equal('use-credentials'); + }); }); }); }); diff --git a/spec/RequestSpec.js b/spec/RequestSpec.js index 78a336948..0df42e295 100644 --- a/spec/RequestSpec.js +++ b/spec/RequestSpec.js @@ -48,6 +48,24 @@ describe('L.esri request helpers', function () { requests[0].respond(200, { 'Content-Type': 'text/plain; charset=utf-8' }, JSON.stringify(sampleResponse)); }); + it('should be able to make a GET request with CORS and credentials', function (done) { + L.esri.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {}, function (error, response) { + expect(this.foo).to.equal('bar'); + expect(response).to.deep.equal(sampleResponse); + done(); + }, { + foo: 'bar', + options: { + withCredentials: true + } + }); + + expect(requests[0].url).to.equal('http://services.arcgisonline.com/ArcGIS/rest/info?f=json'); + expect(requests[0].method).to.equal('GET'); + expect(requests[0].withCredentials).to.equal(true); + requests[0].respond(200, { 'Content-Type': 'text/plain; charset=utf-8' }, JSON.stringify(sampleResponse)); + }); + it('should be able to make a GET request with JSONP', function (done) { var request = L.esri.get.JSONP('http://example.com/foo', {}, function (error, response) { expect(this.foo).to.equal('bar'); diff --git a/src/Layers/RasterLayer.js b/src/Layers/RasterLayer.js index ea0bb2e0a..e554dcb76 100644 --- a/src/Layers/RasterLayer.js +++ b/src/Layers/RasterLayer.js @@ -201,7 +201,7 @@ export var RasterLayer = Layer.extend({ // opacity is 0 while the image is loading var image = new Overlay(url, bounds, { opacity: 0, - crossOrigin: this.options.useCors, + crossOrigin: this.options.withCredentials ? 'use-credentials' : this.options.useCors, alt: this.options.alt, pane: this.options.pane || this.getPane(), interactive: this.options.interactive diff --git a/src/Request.js b/src/Request.js index 249d7416f..87d122385 100644 --- a/src/Request.js +++ b/src/Request.js @@ -104,6 +104,9 @@ function xmlHttpGet (url, params, callback, context) { if (typeof context !== 'undefined' && context !== null) { if (typeof context.options !== 'undefined') { httpRequest.timeout = context.options.timeout; + if (context.options.withCredentials) { + httpRequest.withCredentials = true; + } } } httpRequest.send(null); @@ -128,6 +131,9 @@ export function request (url, params, callback, context) { if (typeof context !== 'undefined' && context !== null) { if (typeof context.options !== 'undefined') { httpRequest.timeout = context.options.timeout; + if (context.options.withCredentials) { + httpRequest.withCredentials = true; + } } } diff --git a/src/Util.js b/src/Util.js index 75b76f7a7..4f8e48d33 100644 --- a/src/Util.js +++ b/src/Util.js @@ -84,7 +84,7 @@ export function _findIdAttributeFromFeature (feature) { export function responseToFeatureCollection (response, idAttribute) { var objectIdField; var features = response.features || response.results; - var count = features.length; + var count = features && features.length; if (idAttribute) { objectIdField = idAttribute;