Ajax Stub - Ajax Patterns

Ajax Stub

From Ajax Patterns

(Difference between revisions)
Revision as of 21:33, 30 September 2010
BerryMolina (Talk | contribs)
Want to Know More?
← Previous diff
Current revision
NooBox (Talk | contribs)
JSON Message
Line 201: Line 201:
In fact, some people are being even more ambitious with JSON. A standard called [http://json-rpc.org/ JSON-RPC] is evolving for a remote call protocol based on JSON, as opposed to the better-known XML-RPC. There's already one [[Ajax Stub]] framework based on JSON-RPC, the aptly named [http://oss.metaparadigm.com/jsonrpc/ JSON-RPC-Java]. In fact, some people are being even more ambitious with JSON. A standard called [http://json-rpc.org/ JSON-RPC] is evolving for a remote call protocol based on JSON, as opposed to the better-known XML-RPC. There's already one [[Ajax Stub]] framework based on JSON-RPC, the aptly named [http://oss.metaparadigm.com/jsonrpc/ JSON-RPC-Java].
- +[http://www.itcreate.net IPhone development]
<!-- =================================================================== --> <!-- =================================================================== -->
- 
-= Want to Know More? = 
-* [http://www.film-izlesek.com film izlsek] 
-* [http://www.antiquesrepublic.com/index.php Antique Cars and Carnival Glass Auctions] 

Current revision

Evidence: 2/3

Tags: Delegate Facade Procedure Proxy Remote Remoting RPC


Contents

In A Blink

Diagram - Client-side passes through to server-side


Technical Story

Devi begins working on the browser script for a trading application and soon decides she needs a way to execute a trade. There's already a method to do that on the back-end class, so after 15 seconds reconfiguring the Ajax Stub, the browser script is able to invoke the method.


Problem

How do you implement an RPC Service?


Forces

  • Some services have to reside on the server, for reasons of security, complexity, and performance. Thus, you need to expose "web services" to be accessed from the browser script.
  • A web service should encapsulate only web-related logic, and delegate any business and application logic to the back-end.
  • This creates a redundancy: the web service and the back-end logic are tied together. When one changes, the other must change, leading to more work and the risk that you'll forget to change one or the other.
  • The browser needs to access web services via XMLHttpRequest over HTTP, which is fundamentally different to the way both Javascript and server-side scripts work. It's tedious to wrap and unwrap messages into a form suitable for transfer.


Solution

Use an "Ajax Stub" framework which allows browser scripts to directly invoke server-side operations, without having to worry about the details of XMLHttpRequest and HTTP transfer. The aim is to let the Javascript call remote operations as if they were regular Javascript functions, facilitating a more natural program style.

There are several frameworks to support stubbing of this nature. Typically, you declare which back-end operations should be exposed, and the framework takes care of the remoting. See the Refactoring Illustration below for the technical details.

Typical facilities include:

  • Ability to convert Javascript arguments and return values into server-side language constructs.
  • Sensible handling of server-side errors and exceptions.
  • Support for general XMLHttpRequest issues, such as timeouts.

The framework usually consists of two components:

  • A Javascript component marshalls the call into an XMLHttpRequest, handles the call, and later unmarshalls the response.
  • A server-side configuration component, with some configuration, that accepts the call, delegates to the back-end operation, and marshalls the return value into a suitable response.


Decisions

How will you secure the server-side function?

With great power comes great responsibility. The Ajax Stub approach gives you both of those. It's easy, bordering on trivial, to directly expose business operations. That means it's also easy to let curious users do things they shouldn't. Since many Ajax applications push the whole user-interface out to the browser, the web tier is left publishing business methods. Harry Fuecks, author of Ajax Stub toolkit JPSpan, gave a cautionary example on the Ajax Blog. A naive export of a business operation could end up with a call like this:

 var ccNum = AJAX.getCreditCardNumber(userId);

Anyone can edit the Javascript and pass any argument to the credit card operation. Another stubbing framework, DWR, advises, "There is a danger that you could cause all sorts of security problems using this code. You need to think about security earlier rather than later."

Other approaches, such as RESTful Service are also vulnerable to this threat, but they tend to encourage more analysis, because you have to explicitly design the service interface. With Ajax Stub, you're effectively ticking a few boxes to say which back-end operations can be executed.

A few guidelines:

  • Even though you can publish an interface very quickly, that doesn't mean you should. Do take the time to consider the implications of making an operation available to the public (or whatever user base will be using your Ajaxian application), who will be able to call it with whatever arguments they please.
  • The framework's module is exposed as a web service - your environment might be able to control access to particular services. For example, the DWR Framework for Java stubbing advises: "Access to dwr can be restricted using the declarative security built into the servlet spec."
  • Depending on the environment, the back-end operation may need to use some form of authentication. In some cases, the operation will have direct access to request information such as the URL and cookies, which will facilitate authentication. The downside is that you've begun to incorporate web-related concepts into the business logic, which is what Ajax Stubs seek to avoid.
  • Be weary of the framework as well. One Ajax Stub framework, CPAINT caused some security alerts due to the possibility of malicious code being executed on the server. The team was quick to respond and the Ajax Stub pattern is not inherently flawed, as some people had assumed. However, it's important to understand just what exactly is exposed by an Ajax Stub framework.

There is a partial security solution that protects the web service and some of the arguments. Before you deploy, encrypt all static arguments in your JavaScript using DES or some other symmetric algorithm. Then just get your web service to decrypt these particular arguments with the same key you used to encrypt them. Obviously the dynamic portion of your arguments can't be encrypted, so you parameterize them first, like such:


GetData("http://localhost:1300/sqlproxy.aspx", "select * from messages where messageID > "+document.getElementByID('lastmessageID').value+" order by messageID desc", fillRepeater)

Becomes

GetData("http://localhost:1300/sqlproxy.aspx?p1="+document.getElementByID('lastmessageID').value, "select * from messages where messageID > [p1] order by messageID desc", fillRepeater)

Then can encrypt the SQL which is now all text:

GetData("http://localhost:1300/sqlproxy.aspx?p1="+lastmessageID, "mClOYezCdw0fA0voRZdbprJVAul61QU04JfxRExpTp5qQ49aj3fWj3iG0OJvp7mFyQISm7JkcCUkiFZB/zuGHmjml6TN2DFlGmA0vdFb+xg=", fillRepeater);

At the server (this is a C# / .NET example), the SQL is decrypted, and decryption fails if the argument was not first encrypted with the key set on the server side. It's then pretty trivial to sub the parameters back into the query with a search-and-replace algorithm, something like this:


           while (!getOut)
           {
               if (input.IndexOf('[', index) > 0)
               {
                   index = input.IndexOf('[', index);
                   endIndex = input.IndexOf(']', index);
                   parameterName = input.Substring(index + 1, (endIndex - index - 1));
                   parameterValue = HttpContext.Current.Request.QueryString[parameterName];
                   input = input.Replace("["+parameterName+"]", parameterValue);
                   index += parameterValue.Length;
               }
               else
                   getOut = true;
           }

And there you have it. Just take the necessary injection precautions on the unencrypted arguments, like you would do if they came from a form field.


Real-World Examples

These examples cover available frameworks for creating Ajax Stubs.

SAJAX

SAJAX is an Ajax Stub framework that actually supports multiple back-end languages. The browser-side is the same for all, but there are different server-side proxy components depending on which language is used. Among the back-end languages are ASP, ColdFusion, Perl, PHP, Python, and Ruby.

DWR

ADWR is an open-source framework for Ajax Stubs to Java classes. On the server-side, you run a DWR servlet and configure it with a separate XML file. In the browser, you just include a Javascript file. Java and Javascript may not have much in common, but calls do at least look the same. A DWR Javascript-to-Java call looks just like a Java-to-Java call.

CL-AJAX

Richard Newman's open-source CL-AJAX supports stubbing of Common Lisp functions.

AJAXEngine

A client-side framework written in JavaScript that allows calling SOAP based standard web services by creating client-side proxies out of wsdl definitions. A proxy generator is available in A# for ASP.NET and Java. AJAX actions is a layer above the pure communication that provides a mechanism of binding asynchronous server calls and the client side asynchronous processing together using a declarative and "good readable" approach in pure JavaScript. This allows features like queueing and delaying of calls, removing dublicate calls anc low level caching. [1]


Refactoring Illustration

In this refactoring illustration, the Basic Sum Demo is refactored to use an Ajax stub, based on SAJAX.

To begin with, we do away with the old Sum service (sum.phtml) and create a standalone, back-end, calculator module. Now that we're using an RPC approach, we'll call the operation add instead of sum, to make it distinctly a verb. So calculator.phtml looks like this:

  <?php

    function add($figure1, $figure2, $figure3) {
      echo $figure1 + $figure2 + $figure3;
    }

  ?>

With the stub, we can allow the browser-side script to directly invoke that function. The Javascript call looks like this.

  function submitSum() {
    x_add($("figure1").value,$("figure2").value,$("figure3").value,onSumResponse);
  }

Here's how SAJAX provides the glue between the Javascript x_add and the PHP add. In PHP, we tell SAJAX which functions are exported.

  <? require_once("Sajax.php"); ?>
    ...
    sajax_init();
    sajax_export("add");
    sajax_handle_client_request();

And in outputting the script, some PHP code generates the required Javascript - in this case, the x_add() function which will forward on to SAJAX on the server-side and eventually interpret its response.

  <script>
    <?
      sajax_show_javascript();
    ?>
  </script>


Alternatives

XMLHttpRequest Call

Ajax Stubs are built on top of XMLHttpRequest Calls and represent a different approach to remoting. XMLHttpRequest Calls leave the user to deal directly with HTTP concepts and packing and unpacking of messages, tasks that Ajax Stubs take care of. The benefit of direct XMLHttpRequest Calls is that the server-side service interface is independent of the underlying implementation.

XML-RPC, SOAP

XML-RPC and SOAP are more generic ways to develop RPC Services. Since Ajax Stubs tend to produce Ajax-specific services, XML-RPC or SOAP might be more appropriate if you're opening up to external clients.


Related Patterns

RPC Service

An Ajax Stub is one way to implement an RPC Service.

JSON Message

JSON Messages are being used by several Ajax Stub frameworks because Ajax Stubs need to share data between browser and server, i.e. inbound arguments and outbound return values. These objects should be standard Javascript objects in the browser, and standard Java or PHP or whatever-your-language-choice objects on the server. In between, they it's most convenient to transfer them as strings. JSON defines a standard way to convert objects in many languages to and from a string representation.

In fact, some people are being even more ambitious with JSON. A standard called JSON-RPC is evolving for a remote call protocol based on JSON, as opposed to the better-known XML-RPC. There's already one Ajax Stub framework based on JSON-RPC, the aptly named JSON-RPC-Java. IPhone development