Project: Using Remoting to Authenticate a User

Before you begin these exercises, you will need an Application Server like ColdFusion MX and a database like Microsoft Access, SQL Server, or SyBase. You can download a trial version of ColdFusion MX from http://www.Macromedia.com/go/coldfusionmx/. We will create and connect the database in this exercise using Microsoft Access 2000. Flash Remoting MX uses the standard HTTP protocol, so you will need a web server installed. For this exercise, Microsoft IIS5.0 web server is our server of choice. You are free to use other servers, including the stand-alone web server included with ColdFusion MX.

The first exercise has broad implications, but we are going to simplify it quite a bit. Remember that array of objects we used back in Chapter 11, "Server-Side ActionScript (SSAS)"? That example was demonstrating the Application object in SSAS using Application.onAppStart to define an array of user objects. You used that array as an authentication challenge when the user logged in. You matched a username and a password with the object properties in the array.

That example can be useful in a simple application that does not require user maintenance. It is also a bad technique to use because you are placing content (user information) in line with the code (ActionScript). A better technique is to use a database or an LDAP server to store user information. You could build another interface to manage the user information, without recompiling the application each time you want to make a change.

This project will step you through four exercises that will result in a fully functional application that will authenticate against a database. Here's an overview of the exercises:

  • Exercise 13.1: Setting Up the Database

  • Exercise 13.2: Creating the Database Call

  • Exercise 13.3: Consuming the CFC as a Web Service in Flash Communication Server

  • Exercise 13.4: Calling Flash Communication Server and Establishing a Connection Using Flash MX

Let's jump in with our first exercise to construct the database.

Exercise 13.1: Using Remoting to Authenticate a User

Assuming that you have ColdFusion MX installed and running, this first exercise will walk you through building a simple database using Microsoft Access. You can use most common database technologies supported by ColdFusion MX. Follow these steps to construct your database:

  1. Create a folder in the ColdFusion MX server's default web directory. Call the folder myFlashComService. This folder name is important and will be referenced later on in this exercise.

  2. Open Microsoft Access.

  3. Create a blank Access database with the name myFlashComDb.mdb (see Figure 13.1). Save the database file in the folder you just created, or a folder accessible by the ColdFusion Server.

    Figure 13.1. When MS Access opens, you will be prompted. Select Blank Access Database. You can also access this screen by selecting File, New in the MS Access Command menu.

    graphics/13fig01.gif

  4. Build a database table using the Create Table in Design View feature (see Figure 13.2).

    Figure 13.2. Add tables to the database using the Design View Wizard.

    graphics/13fig02.gif

  5. Create a series of fields in the database. The field list should include the following (see Figure 13.3):

    Field Name

    Data Type

    UserID

    AutoNumber (key)

    fname

    Text

    lname

    Text

    login

    Text

    password

    Text

    emailAddr

    Text

    phoneNum

    Text

    streetAddr

    Text

    Figure 13.3. Your field list should look like this. Don't forget to change the Allow Zero Length property to No.

    graphics/13fig03.gif

  6. Assign the UserID as the key, or unique identifier. You can do this by selecting the field and clicking the Key icon in the toolbar.

  7. Change the value of Allow Zero Length to No for every field.

  8. Close the table and save it as Users (see Figure 13.4). Note that this table name will be used at a later point in this exercise, so if you do not name the table Users, remember what name you gave it.

    Figure 13.4. Save your table as Users. This is referenced later, so remember the name you choose.

    graphics/13fig04.gif

  9. Populate the table with some values (see Figure 13.5).

    Figure 13.5. Populate your Users table with some data. Remember some of the logins/passwords.

    graphics/13fig05.gif

  10. Save and close MS Access. Your database is complete and ready to go!

Now, connect the database to your ColdFusion MX server using the Data Sources window:

  1. Open the ColdFusion Administrator and Login.

  2. Click the Data Sources link in the Administrator menu.

  3. Add a new datasource: Enter myFlashComDb in the Data Source Name field and select the driver Microsoft Access, and then click Add.

  4. Browse the server for the database file you just created (see Figure 13.6).

    Figure 13.6. Connect the database to a ColdFusion MX data source using the ColdFusion MX Administrator.

    graphics/13fig06.gif

  5. Click Submit and ColdFusion will verify the database. If you get an error, click the new data source name in the list and confirm that you have referenced the correct database file.

Now you are ready to rock and roll! We will use this database for other examples in this chapter.

Exercise 13.2: Build the Macromedia ColdFusion Script

With the database connected and ColdFusion all set up, you are ready to build the ColdFusion script. This script will expose a method returning a simple Boolean?true or false value?to the Communication Server. This method will require two parameters?can you guess which two? That's right, login and password. Each parameter will be a string. First, on to the ColdFusion:

  1. Create a new folder in the default web server called myFlashComService.

  2. Create a ColdFusion Component (CFC) file called login_service.cfc in the myFlashComService folder. (Macromedia Dreamweaver MX users can use the Create ColdFusion Component Wizard by selecting File, New, Dynamic Page, ColdFusion Component.) This creates a new CFC template.

  3. Open the login_service.cfc file in your favorite HTML editor. Dreamweaver MX has some excellent helper applications to build the ColdFusion components.

  4. Add the following script to define the CFC and the method that will be called by the Flash Communication Server:

    <cfcomponent> 
                <cffunction name="authenticateUser" access="remote" returntype="boolean">
    

    The <cffunction> defines the name of the method you will call in Flash Communication Server. Dreamweaver MX users can use the Tag Editor to create the function (see Figure 13.7).

    Figure 13.7. The Dreamweaver MX Tag Editors offer GUIs for each ColdFusion tag. To access the GUI, enter the tag <cffunction>, and then right-click the tag and select Edit Tag.

    graphics/13fig07.gif

  5. Create two arguments that will handle the data sent from Flash Communication Server:

    <cfargument name="login_str" type="string" required="true" default="null"> 
    <cfargument name="password_str" type="string" required="true" default= "null">
    

    Dreamweaver MX users can use the Tag Editor to create the arguments.

Now, create the database call using ColdFusion's <cfquery> tag and some SQL:

  1. Open the database connection. In this tag, define the name of the query so you can access the results later. Also, define the datasource you assigned in the ColdFusion Administrator:

    <cfquery name="checkUser" datasource="myFlashComDb"> 
    
  2. Create the database SQL. This returns all the UserIDs of users with login and password equal to the arguments passed to the method from the Flash Communication Server:

    SELECT UserID 
    FROM Users
    WHERE       login = '#arguments.login_str#' and
                password = '#arguments.password_str#'
    

    Tip

    You can also use a database function called Count to return the number of records from a database table. This function returns the number of rows that match the WHERE condition. This is a good idea if you have a lot of records in the database. In the preceding example, there would be x rows returned to the Application Server. In this example, there would only be one row returned with a single value:

    SELECT Count(UserID) as Total FROM... 
    
    Select Count(*) as Num from Users
    
  3. Close the <cfquery> tag:

    </cfquery> 
    
  4. Use script to challenge the recordCount of the query. If one record was found, set the isLoginOK value to true. In this exercise, you will use CFScript, which is very similar to ActionScript in format. There are unique iterations of some operations, such as using IS or EQ versus == to match string values, as shown in the following code:

    <cfscript> 
          if (checkUser.recordCount is 1) isLoginOK = true;  else isLoginOK = false;
    </cfscript>
    
  5. Return the Boolean value to the Flash Communication Server:

    <cfreturn isLoginOK> 
    
  6. Close the function and the component:

          </cffunction> 
    </cfcomponent>
    

That's it for the ColdFusion part of the application. You can run this CFC directly in a web browser. If everything is good, you will see a full description of the component including all methods with their return values:

http://localhost/myFlashComService/login_service.cfc

Tip

You can also reference this CFC as a standard WSDL Web Service by placing a ?wsdl parameter following the filename in the address bar of your browser:

http://localhost/myFlashComService/login_service.cfc?wsdl


Exercise 13.3: Consume the CFC as a Web Service in Flash Communication Server MX

Now that you have the ColdFusion Component set up and ready to go, you are ready to consume the CFC as a Web Service in the Flash Communication Server. We'll start at the server and then move to Flash MX to build the interface:

  1. Create a new application folder called myRemotingApp within the Flashcom Applications folder on the server.

  2. Create the main.asc file in the new myRemotingApp folder.

  3. Open the main.asc file in your development environment. Remember, you can edit server-side ActionScript (SSAS) scripts using a simple notepad-type editor like JavaScript Editor or Dreamweaver MX.

  4. Load the NetServices class files. This gives you access to the methods required to communicate with Application Services using Flash Remoting MX and the AMF format:

    // Load the NetServices Class Libraries 
    load("netservices.asc");
    

    Note

    This exercise does not use any Communication Server UI components, so there is no need to include them here. If your application uses the Communication Server UI components, you will have to load them:

    load("components.asc"); 
    
  5. Overwrite the Application.onConnection method, requesting two additional parameters: username and password:

    application.onConnect = function(clientObject, username, password) { 
    
  6. Set the default gateway for NetServices. This is the name of your ColdFusion (or Remoting) server. Note that in ColdFusion, you must attach /flashservices/gateway to the URI to enable Flash Remoting MX. This is not a folder on the server. This reference points to the wwwroot of your default web server (if you are using Windows IIS):

    NetServices.setDefaultGatewayUrl("http://127.0.0.1/flashservices/gateway"); 
    
  7. Instantiate the gatewayConnection to a custom variable gatewayConnection:

    var gatewayConnection = NetServices.createGatewayConnection(); 
    

    Note

    If you want to use this connection anywhere else, you can set it as an application variable?for example, application.gatewayConnection. Or, because you are setting it within the application scope in onConnection, you can use this.gatewayConnection.

  8. Instantiate ColdFusion Component script or Web Service. The parameter within the getService method uses the dot syntax to define folders and files. In this example, the parameter is referencing the file login_service.cfc in the folder myFlashComService within the default web site:

          //  instantiate the service into a local variable 
          var cf_service =
    gatewayConnection.getService("myFlashComService.login_service", this);
    

    CFFunctions, or methods defined in the service (ColdFusion Component), can be called using the custom variable cf_service.

  9. Call the service as you would any regular ActionScript function, passing the required parameters?in this case, username and password:

    // call the server function, authenticateUser, passing the username and password 
    var callTheServer = cf_service.authenticateUser(username, password);
    

Note

You don't need to use the variable callTheServer, but you can use it to challenge if the function was run. If the function ran, the variable will contain the Boolean value true, and if it didn't run, it will contain the value false. This is helpful for debugging.


Just like NetConnection, or Stream, the service function returns either a Result or Status message to Flash Communication Server. The syntax is a bit different than you have seen. The name of the service function is suffixed with a _Result (remember, it's case sensitive and requires a capital R). If the function returns an error, it looks for the function with the same name, suffixed with a _Status. These next steps use this method, but you can also create a prototype handler for this, using an onStatus or onResult custom function:

  1. Create the _Result function with one parameter to handle the returned data (as scripted in the CFCs <cfreturn> tag):

    // handle the server response 
    this.authenticateUser_Result = function (result_boo) {
    
  2. Place a simple trace so you can monitor activity within the App Inspector:

    trace("The Server Responded, good for you! ?> " + result_boo); 
    
  3. Call a function to accept or reject the connection. The function you are calling will be scripted shortly. It will require two parameters: a Boolean value declaring an accept or reject and the clientObject. This script also contains the closing function bracket:

          // call the challengeConnection Function, which will accept/deny the connection 
          challengeConnection(result_boo,clientObject);
    };
    
  4. Create the error handler for the function using _Status. This handler also calls the challengeConnection function, passing a value of false to trigger a connect rejection. This is the last bit of code for the onConnect function, so include the closing function bracket:

          // handle any server errors 
          this.authenticateUser_Status = function (status) {
                trace("Returned FAILED From the Server");
                challengeConnection(false,clientObject);
          };
    // close the onConnect function
    };
    
  5. Create the function challengeConnection to handle accepting or rejecting connections based on the server results. This function requires two parameters: a Boolean value and the clientObject:

    challengeConnection = function(isAuthenticated, clientObject) { 
    
  6. Challenge the Boolean value passed from the caller (also known as the server) for a true or false value. With Boolean values, you are not required to place the sequence ==true or ==false. If the value is true, accept the connection; if not, reject it. This script also closes the challengeConnection function:

          if (isAuthenticated) { 
                trace("You have entered the inner sanctum");
                application.acceptConnection(clientObject);
          } else {
                trace("Not today, my Friend...");
                application.rejectConnection(clientObject);
          }
    }
    

That's it for the server(s). You can check your code in the App Inspector to make sure everything compiles correctly. Load the App Inspector, log in, and enter the following line into the App Inspector input field and click Load: myRemotingApp/myInstance. This compiles the application into the myInstance instance. If your code doesn't compile properly, you will see a Warning symbol show up on the App Inspector. Double-click it to determine the error.

A better way to accomplish this is to click View Detail with the new instance selected. This opens the Live Log panel. Click the Reload App button and the trace actions are displayed in the output window. This window also displays any compile errors with some details where the errors occurred. Figure 13.8 is an example of what your Trace window should look like.

Figure 13.8. The App Inspector is used as the SSAS Trace output window. When you click the Reload App button, your output should look like this.

graphics/13fig08.gif

Exercise 13.4: Call Flash Communication Server and Establish a Connection Using Macromedia Flash MX

This final exercise will move into Flash MX. To save time on this exercise, you will not build an interface. Our objective is to call Flash Communication Server and establish the connection. It's a real simple application, but it will build the foundation for you to construct secure applications:

  1. Create a new Flash movie called mySecureApp.fla and save it in your work folder, or on the Flash Communication Server, in the myRemotingApp folder.

  2. Open the ActionScript panel (F9).

  3. Instantiate the NetConnection object to the variable nc:

    nc = new NetConnection(); 
    
  4. Create a simple onStatus function for the NetConnection that lets you watch the connection either be rejected or connected:

    nc.onStatus = function(info) { 
          trace("LEVEL: "+info.level+"  CODE: "+info.code);
    };
    
  5. Connect the movie, passing a valid login and password to the Application.onConnect function:

    nc.connect("rtmp:/ myRemotingApp/myInstance", "tin", "can"); 
    

That's it! You're now ready to test your application. But before you do, understand what is going to happen. Your Flash MX output window will inform you if the connection was accepted or rejected. The App Inspector Live Log panel will output the trace actions you scripted in your main.asc file. Because you don't have an interface with this application, these are your only tools to determine if your connection was successful or not. Figures 13.9 and 13.10 show what a successful connection looks like when you test your movie (Ctrl+Enter).

Figure 13.9. The Flash MX output window showing the accepted connection.

graphics/13fig09.gif

Figure 13.10. The App Inspector Live Log panel showing the accepted connection.

graphics/13fig10.gif

When you have made a successful connection, try to log in with a bad username and password. Close the test movie and enter an INVALID username and password into the connect function. Then, test your movie again. Monitor the output window and the App Inspector. You should see output similar to what's shown in Figures 13.11 and 13.12.

Figure 13.11. The Flash MX output window showing the rejected connection.

graphics/13fig11.gif

Figure 13.12. The App Inspector Live Log window showing the rejected connection.

graphics/13fig12.gif

You will obviously need to extend this exercise to put it into proper use. The most common method would be to place two input text fields on your Flash stage, giving them instance names of login_txt and password_txt. Change your Connect string to the following:

nc.connect("rtmp:/ myRemotingApp/myInstance", login_txt.text, password_txt.text); 

SSAS on Macromedia ColdFusion MX

ColdFusion MX also fully supports Flash MX ActionScript (on the server) to interact with a database. Using the file format .ASR, ColdFusion MX interprets the script as ActionScript. Unique ColdFusion objects are available, including a database query method. The entire ColdFusion Component that you created in the previous exercise could have been scripted like this within the login_service.asr file stored in the same folder:

function authenticateUser(login,password) { 
      theSQL = "SELECT UserID FROM Users WHERE    login = '#arguments.loginstr#' and 
graphics/ccc.gifpassword = '#arguments.passwordstr#'";
      checkUser = CF.query({datasource:"myFlashComDb", sql: theSQL});
      if (checkUser.recordCount ==1) isLoginOK = true;  else isLoginOK = false;
      return isLoginOK
}


    Part I: 10 Quick Steps for Getting Started
     
    ASPTreeView.com
     
    Evaluation has јГВРХЪИЩexpired.
    Info...