Web App Start-up with Validation and Bailout if Need Be

4702
9
Jump to solution
05-08-2015 04:58 PM
DavidPlume1
New Contributor III

Hi - I'd like to locate logic in my application start-up to call a service and authenticate a user on that service.  If the user is OK then finish app start up.  If not OK then show message, stop loading and cleanup.  Where should this login be located?  More robustly, you could have code to dialog with the user until the user gives the correct credentials or chooses cancel.  

In Firebug I can see lots of potential locations - seems like index.html,  function loadingCallback() would be the best location but I'm open to other suggestions.

Importantly - on bailout what would be the best way to dispose of all of the WAB objects and leave the user in a sensible space?

Thanks!

1 Solution

Accepted Solutions
LarryStout
Occasional Contributor III

David,

Another approach is to add a reference to a JavaScript file from index.html right after the simpleLoader.js:

    <script type="text/javascript" src="validateCredentials.js"></script>

validateCredentials.js would look something like this:

(function waitForAPI() {
  if (typeof require === 'undefined') {
    if (window.console) {
      console.log('Waiting for API to be loaded.');
    }
    setTimeout(waitForAPI, 100);
    return;
  } else {
    validateCredentials();
  }
  
  function validateCredentials() {
    require([
      'dojo/aspect',
      'dojo/Deferred',
      'jimu/utils'], 
    function (aspect, Deferred, jimuUtils) {
      aspect.around(jimuUtils, 'createWebMap', function(originalMethod) {
        return function(portalUrl, itemId, mapDiv, options) {
          var mapDeferred = new Deferred();
          var success = checkCredentials();
          
          if (success) {
            originalMethod.call(jimuUtils, portalUrl, itemId, mapDiv, options).then(function(deferred) {
              mapDeferred.resolve(deferred);
              return;
            });
          } else {
            map.remove();
            mapDeferred.reject();
            window.location.assign("http://www.arcgis.com/home/");
            confirm('Credentials not Valid');
          }
          
          function checkCredentials() {
            // Put your code here.  Return true if credentials are valid, false otherwise.
            return false;
          }
          
          return mapDeferred;
        };
      });
    });
  }
})();

Larry

View solution in original post

9 Replies
RobertScheitlin__GISP
MVP Emeritus

David,

  I would say do this in an asp.net wrapper so that the WAB code is never touched until the user is authenticated. I do this for some of JS API apps using Forms Authentication.

DavidPlume1
New Contributor III

Robert,  that just goes to show how one can get so wrapped up in one framework they loose their brain and forget about all the other tools in their toolbox.  Thanks!

0 Kudos
shafitrumboo
New Contributor III

Thanks for your valueble input now can you please guide how to disable some tools in WAB. And also I want to know how to validate user in WAB page as the page is .html and don't have any server side validation. I mean if i have url of index.html it can not check if user has loged in or not

0 Kudos
LarryStout
Occasional Contributor III

David,

Another approach is to add a reference to a JavaScript file from index.html right after the simpleLoader.js:

    <script type="text/javascript" src="validateCredentials.js"></script>

validateCredentials.js would look something like this:

(function waitForAPI() {
  if (typeof require === 'undefined') {
    if (window.console) {
      console.log('Waiting for API to be loaded.');
    }
    setTimeout(waitForAPI, 100);
    return;
  } else {
    validateCredentials();
  }
  
  function validateCredentials() {
    require([
      'dojo/aspect',
      'dojo/Deferred',
      'jimu/utils'], 
    function (aspect, Deferred, jimuUtils) {
      aspect.around(jimuUtils, 'createWebMap', function(originalMethod) {
        return function(portalUrl, itemId, mapDiv, options) {
          var mapDeferred = new Deferred();
          var success = checkCredentials();
          
          if (success) {
            originalMethod.call(jimuUtils, portalUrl, itemId, mapDiv, options).then(function(deferred) {
              mapDeferred.resolve(deferred);
              return;
            });
          } else {
            map.remove();
            mapDeferred.reject();
            window.location.assign("http://www.arcgis.com/home/");
            confirm('Credentials not Valid');
          }
          
          function checkCredentials() {
            // Put your code here.  Return true if credentials are valid, false otherwise.
            return false;
          }
          
          return mapDeferred;
        };
      });
    });
  }
})();

Larry

DavidPlume1
New Contributor III

Larry,

Excellent - I think this was just what I had in mind.  Thank you for your thoughtful code example!

David.

DavidPlume1
New Contributor III

Larry,

If you have time and interest I'm wrestling with the asynchronous nature of javascript and the problems introduced with the posting of an EXT.JS web form to get and validate the user name and password.

Using the code below I raise the following form but have two problems.  The form is not active and seems to be hidden behind the Loading div??  how can I turn off the loading widget and is it plausible that the form is inactive because it is behind the loading div.

LoginFormAndLoading.png

Anyway - here is my implementation of the code:

index.html, body:

indexGraphic.png


( function waitForAPI() {  


  if (typeof require === 'undefined') {
   
    if (window.console) {  
      console.log('Waiting for API to be loaded.');  
    }  
    setTimeout(waitForAPI, 100);  
    return;  
  } 
  else 
  {  
    validateCredentials();  
  }  
    
  function validateCredentials() {  
    require([  
      'dojo/aspect',  
      'dojo/Deferred',  
      'jimu/utils'], 
   
    function (aspect, Deferred, jimuUtils) {  

  aspect.around(jimuUtils, 'createWebMap', function(originalMethod) {  
   
        return function(portalUrl, itemId, mapDiv, options) {  

          var mapDeferred = new Deferred(); 
   
   var authDefer = new Deferred();
   var authResult = null;


   // Set up the authorization deferrer:
   
   authDefer.then(


  //Callback after resolution of the deferrer
  function (authResult) {


  //ServiceStatus < 0 indicates the call to the service is incomplete.  0 indicates Cancel, > 0 indicates the service has executed, See Result for success or failure)
  //authResult =  { ServiceStatus: N, ServiceResult: "STRING", bIsAuth: Bool };

   if (authResult.bIsAuth) { 
   
  originalMethod.call(jimuUtils, portalUrl, itemId, mapDiv, options).then(function(deferred) {  
   mapDeferred.resolve(deferred);  
   return;  
  });  
   } 
   else 
   {  
  map.remove();  
  mapDeferred.reject();  

  window.location.assign("http://localhost/wab1/NotAuthorized.html");  
  confirm('Credentials not Valid');  
   }  
   
  }
  );


  // Call this with authDefer and wait for resolution
  r5AuthMod.Authenticate("EPAOSC_Token", authDefer);

  return mapDeferred;
  //return authDefer;

        };  
      });  
    });  
  }  
})();  
0 Kudos
LarryStout
Occasional Contributor III

David,

I've been offline for a couple of days.  It looks like Robert has answered your question.  His answers are usually better than mine.  I wish we had several of him.

Are you set now?

Larry

0 Kudos
DavidPlume1
New Contributor III

Larry,

Thanks very much - yes, I'm good.  I wish we had several of both of you!

David

KumarHarish
New Contributor III

David,

I am newbie.

Similar to yours " I'd like to locate logic in my application start-up to call a service and authenticate a user on that service.  If the user is OK then finish app start up".

I have seen you have scuccessfully  implemented that part.  I would appreciate if you could share in detail so that I can start implementing it.

Thanks

Kumar

0 Kudos