Data Driven Programming with JQuery – Part 2

In the first part of this series, we showed how to use JQuery to select various elements on an HTML page with amazing efficiency and effectiveness. We also demonstrated the use of the JQuery data cache and ChainJS plugin for executing HTML templates for JSON result data.  In this new section we will build on lessons learned and what are some key concepts to take away from this.

So lets first summarize what we are doing and the decision we have made. We have decided to create a service based system that will call upon various web services requesting data.  This data will be transmitted back using JavaScript Object Notation and then bound to an HTML template for each time in the result. For this process we will use ChainJS to perform equivalent work on each iteration.

Using this approach we realized a couple things: 1) We generated good code with excellent verbosity and clarity, 2) we moved HTML generation from JavaScript to the view where it belongs.  This second point is critical in modern JavaScript application design.  In the past it was acceptable to generate JavaScript in script blocks as means of creating repetitive or dynamic content.  However, we now have new options when it comes to addressing these scenarios. 1) If the piece of HTML is repetitive it can be displayed via templates and hidden content blocks, this will increase the amount that is INTIALLY sent to the browser, but by having the HTML there it allows you to more easily perform client side operations, this allows you to make the page more utilitarian.

You other option, which I like to use if the action requires heavy processing, is a lazy load. This works by calling a service from the server which returns pure HTML, this HTML can then be used on the client. The advantage of this system is that it trains the user to understand that this operation takes time. And by combining with a system providing instant feedback, the user patience for this feature can be increased.

In both of these features, you notice that at no time did we mention we would generate or build the HTML in the script itself.  This is because such a practice is highly unmaintainable and results in high coupling between the Interaction and Presentation/View layers.  The methods above both either retrieve or generate their HTML in other places.  In the second method, for example, one of the common tricks in ASP .NET programming is to render a user control as a string in a web service and returns its HTML, or use the JQuery.Load function to bring existing HTML into the model.

So now that we have talked about why it is important to think about what you want to accomplish and explore the options available, lets look at another aspect of Data Driven programming: obfuscation.

Obfuscation becomes critical in client data driven applications because we have to remember that JavaScript is client side and fully visible to the client, be they benign or malignant.  One of the ways I obfuscate my code is making intensive use of JavaScript closures, let me demonstrate:

$("#rpter").items( jsonResult ).chain(function() {
    var data = this.item();
    $(".aLink", $(this)).click(function() {
        CallWebService( data.PersonId, function(success) {
            // handle the success callback
        });
    });
});

You will notice that at no time do we ever store PersonId on the page, yet we can reference this code over and over again from different instances of the link and we will get a sort of late binding for the data here.  This is because of the way JavaScript implements “scope convergence”. In this example, two different scopes are combined via the use of an anonymous function (we say an example of this in part 1), and the data is persisted to the JavaScript runtime for later use.  This sort of obfuscation makes it much more difficult for a would-be attack to mutate data prior to being sent to the server.

This bring me to the final piece of discussion in data driven programming: security.  One of the great things about ASP .NET and its view state model is that it is able to pick up mutations to the DOM with respect to controls and throw an error to prevent the data from posting.  However, as we all know, view state information can make pages heavier and decrease performance.  A data driven programming circumvents these performance concerns but at the cost of opening up the system more.

Generally speaking, data driven application rely heavily on services and JavaScript and thus expose more of what can be done to the client.  Using a tool like FireBug, an external user can call and receive data from web services in any form they want, they can even wire up their own events on the page to call the services.  Because of this, it becomes crucial to secure your services and ensure that a request to them is from a legitimate user and for a legitimate cause.  Most services are capable of reading existing session information, and can access values stored in this matter. But as you clean and validate user inputted data, even more so do you need to clean the user data in addition to ensuring proper credentials.  Consider the following scenario:

You implement a web service that provides a variety of commands for both authenticated users and unauthenticated users.  One of these methods allows you to return a list of the users on the system and another takes a username and changes the password to a new password.  An attacker sniffing around the unauthenticated part of your site, see’s this reference and explores the service.  Upon noticing the GetUsers service, he adds an HTML link to your page (using FireBug) and wire up a call to this service.  He is able to get the list of users and finds the admin user, he then creates another button in which he changes the admin password to something he can use.  He then logs into your system with full admin rights.  What can he do?

This is a very real scenario and something that enterprise applications must be prepared to do.  Obviously, the first problem with this setup is the lack of division amongst services.  The first level of obfuscation is preventing users from seeing the entire directory structure or where certain resources might be located.  By separating out the service methods depending on context you can hide the methods you dont want certain people to see.  But the most important thing is to validate your users.  For instance, clearly only a certain set of users can get a list of all users, you might want to check that the user requesting has those rights.  Changing the password should require the original password as well as a validation check that you are allowed to change this password.  There are other things you should look/check for, but those are a couple of the more obvious ones.

In conclusion, the game has changed again; people expect sites to do more and expect them to do it faster and with more style then ever before.  Using the concepts of data driven programming in conjunction with a top notch JavaScript framework and back end programming infrastructure you can quickly and easily create these sort of applications.  JavaScript has become a very important cog in the way we create web applications.  Modern end user machines tend to be very powerful.  We can leverage the power of these machines by moving certain operations from the server to the client and thus lessening the server’s work and relegating it to performing operations more important then simply serving out repetitive bits of HTML.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s