Articles Archive
Articles Search
Director Wiki
 

Portable Password Pages

July 25, 2001
by Paulmichael Blasucci

Editor's Note: This article shows how to use XML in Director to create a simple login system. It's not intended to provide a secure password protection solution.]

The scenario: one of your clients wants user logins for part of her web site. Nothing fancy or secure; just something to control user interaction. It should be in place quickly, inexpensively, and the client should be able to maintain it without contacting you or getting her MCSE certification.

The solution: use an XML file, some Lingo, and pinch of JavaScript to create a flexible web site login module. It's platform and browser indifferent, very portable and scalable, and—once in place—can be maintained by anyone with a high school education and a word processing program. (Note: this tutorial makes two assumptions. First, it assumes you know some basic Lingo and have written a few simple scripts in director. Second, it assumes you understand the basics of XML. For more detailed info on eXtensible Markup Language, check out: Zac Belado's DOUG article or http://www.w3.org/XML/).

See the sample movie in action.

The process: first of all, you'll need a fairly simple XML file. It should, of course, contain a root element. And, most importantly, one or more child elements. Each child element will need three attributes. For example:

<?xml version="1.0"?>
<validate>
<client username="smith" password="john" target="john_smith.htm"/>
<client username="thomson" password="tom" target="tom_thom.htm"/>
<client username="lewis" password="dana" target="dana_lewis.htm"/>
</validate>

In the code above, <validate> is the root element and each <client> is a child of the root element. Each child, in turn, has three attributes: username, password, and target. The username and password are text values that should correspond to some text input from the end user. The target, then, is the url that the end user gets directed to after he has successfully entered the correct username and password. That's all the XML you'll need. Now this file can be uploaded to a web server--presumably the client's, but really anywhere on the World Wide Web will do.

Now for the Lingo. Fortunately, the good people at Macromedia have created an XML Parser Xtra that works fairly well. But, it is a little buggy when parsing a file over the Net. So, as a simple work around, you can use standard network Lingo to download an XML file into your Shockwave movie, then use the XML Parser on it as though it were a local file (eg: embedded into the movie). Don't worry if this sounds a little convoluted. It will become clear by the end of the tutorial. So, start by creating a parent script to handle the file download.

global gXmlObject
property pNetId, pStatus

on new me

  return me

end

on downloadFile me, theFile

  pNetId = getNetText (theFile)
  pStatus = 0
  cursor 4

end

on downloadStatus me

  if pStatus = 0 then
    if netDone (pNetId) then
      if netError (pNetId) = "OK" then
        gXmlObject.parseString (netTextResult (pNetId))
        if gXmlObject.doneParsing () then
          if voidP (gXmlObject.getError ()) then
            pStatus = 1
            go frame "input"
            cursor 0
          else
            alert (“error parsing")
          end if
        else
          alert (“error downloading")
        end if
      end if
    end if
  end if

end

The first handler in this script is a standard birthing handler used to create a new instance of the object. The second handler (downloadFile) receives a URL as a parameter (theFile) and uses that to initiate a getNetText method. The whole thing is put into a property (pNetId) so that the third handler can track it. Another property (pStatus) is created to help keep track of the download. The third handler (downloadStatus) is a series of nested if...then statements that follow a fairly logical path. First, it checks to make sure that a Net operation is in progress (pStatus = 0, note that pStatus = 1 would signify that nothing is currently being downloaded). Next, if the download is done (netDone (pNetId)) and there were no errors during the download process (netError(pNetId) = “OK"), it sends a command to the XML Xtra to parse the text of the downloaded file (gXmlObject.parseString (netTextResult (pNetId))). Finally, it checks to make sure that there were no errors while parsing the text and, if all the above conditions were met, it changes the download status (pStatus = 1) and moves the playback head to a new position to await further orders. Note that if an error does occur while downloading or parsing the file, an alert command is fired.

Moving on, you now need to create a movie script with two handlers: a startMovie handler to initialize everything and the very important evalScript handler that will be used for the actual validation of user input data.

global gNetObject, gXmlObject

on startMovie

  gNetObject = script ("netObject").new ()
  gXmlObject = xtra ("xmlParser").new ()
  targetFile = "userPass.xml"
  gNetObject.downloadFile (targetFile)

end

on evalScript (arguments)

  put arguments
  uName = arguments.item[1]
  uPass = arguments.item[2]
  i = 1
  repeat while i <= gXmlObject.child[1].count (#child)
    tempName = gXmlObject.child[1].child[i].attributeValue["username"]
    tempPass = gXmlObject.child[1].child[i].attributeValue["password"]
    tempUrl = gXmlObject.child[1].child[i].attributeValue["target"]

    if uName = tempName then
      if uPass = tempPass then
        goToNetPage (tempUrl, "_self")
        exit repeat
      else
        errMessage = "invalid password"
        alert (errMessage)
        exit repeat
      end if
    else if i = gXmlObject.child[1].count (#child) then
      errMessage = "invalid username"
      alert (errMessage)
      exit repeat
    else
      i = i + 1
    end if
  end repeat

end

Note that an instance of the XML Parser and an instance of the net object have been assigned to global variables (global gNetObject, gXmlObject). This is important because it allows these objects to receive messages from anywhere in the movie. Next, the evalScript handler receives a line of text. Actually, it is user input data passed to the movie from the browser via JavaScript. This line is then broken into two separate pieces of text: one for the username input value (uName = arguments.item[1]), and one for the password input value (uPass = arguments.item[2]). Then, you have a repeat loop that steps through the parsed XML and compares each username and password from the XML file with whatever values were input by the user (if uName = tempName... uPass = tempPass then). If the correct match is found, the repeat loop is exited and the browser is redirected to the appropriate page (ie: the url indicated by the target attribute from the XML file). If no correct match is found, an alert command is fired—indicating whether the offending value was the username data or the password data.

That's pretty much all the Lingo. The only other things that need to be done in Director are to set up a two-frame movie. The first frame has a frame script the polls the net object for the download status while looping in place.

global gNetObject

on exitFrame me
  gNetObject.downloadStatus ()
  go the frame
end

When the download is complete (pStatus = 1), the object jumps the playback head to frame two, which contains a simple one-frame loop.

on exitFrame me
  go the frame
end

Note that there are no actual sprites placed on your stage! Finally, set your stage size to two pixels wide by two pixels high! This shockwave will be “invisible" to the end user. Thus allowing for total graphical and logistical compatibility with an existing web site--not to mention a tiny file size (about 4K).

So, the only thing that's not in place is the user interface. All we need for this is a basic html page with a standard form: two text input boxes and a submit button. Create the html with your favorite WYSIWYG editor (or hand code it if you're so inclined) and then all the source code needs just a little JavaScript added in two key places. First, in the header you place a simple function declaration.

function submitForm() {
  args = document.testForm.username.value + "," + document.testForm.password.value;
  document.userPass.EvalScript(args);
}

This function takes the user input values from the two form text boxes (note: testForm is the name of the form, username is the name of the first text box, and password is the name of the second text box) and strings them together. Then it passes them to the Shockwave movie via the evalScript handler (note: userPass is the name of the Shockwave movie object in the OBJECT/EMBED tag) and Lingo does the rest.

The last piece of JavaScript is an actual call to the function. This gets wired directly to the form submit button.

<INPUT type="button" name="cmdSubmit" value="Submit" onClick="submitForm()">

And that's it. Just throw all the files up on your favorite web server and presto Of course, this is not the penultimate solution. You could, for example, have the end user type his data directly into a shockwave text box and, thus, totally eliminate the need for JavaScript. Really, the range of uses for this type of technology is limitless. Go nuts. Have fun. And happy coding.

A Director 8 movie is available for download in Mac and Windows archives.Because this movie accesses external files, running from your hard drive within a browser requires that the movie path contain a folder named dswmedia. Newer versions of Netscape Navigator (both platforms) and Internet Explorer (all versions on the Mac) may fail due to problems with the JavaScript/Shockwave interface.

Recipe for Paulmichael Blasucci: - put equal parts information architect, graphic designer, and programmer into medium-sized container - stir until evenly blended - garnish with a silly hat - serve chilled

Copyright 1997-2024, Director Online. Article content copyright by respective authors.