An example of using and maintaining login information in a CGI can be found in the contrib/saLogin_Example directory of the Sapphire/Web distribution. To run the example, create a directory for your project and copy in the contents of the contrib/saLogin_Example directory. Follow the instructions in the README file. There are three HTML files in this directory.
The first file, saLogin.html, is a generic database login form. This or something similar, should be used as the first screen for logging into a CGI or at least a subpart of a CGI application. The most important features of this login form are two input elements. The first element is a text box with a name of "USERNAME" for the user to type in their name. The second element is a password element with the name, "PASSWORD" for the user to type in their password (with those asterisks). You can make use of the fact that you know these two element names to handle the generic login design.
The file, saSetupLogin.c, contains the functions that implement this design. You will at least want to customize the encryption and decryption functions in that file, since they do no encryption. Include the source file's include file in your Main and add a Call to the Function, saSetupLogin(), in your final code of your main. Now there are several cases to examine. The login screen will be handled first.
The login function first determines that it is being called with a standard login screen by looking for the presence of the two elements: PASSWORD and USERNAME. With the values from these two elements, the login function sets the login information. It also encrypts both values so that they can be returned to the client browser thus maintaining the login information.
Now there are three cases to consider as to where the state must be stored in the return HTML. We will consider another form, but without login elements, first. Look at the second HTML file, saAuthorList.html. This HTML file contains another form with two hidden elements. The names of these elements are : EUSERNAME and EPASSWORD. We will make use of these standard encrypted hidden Form Element names later, when we handle this form's input. Also note that the VALUEs for each of these hidden elements have standard data site names: EUserName and EPassWord, respectively. Once you have encrypted login information, you register a Data Site String Function which will substitute these encrypted values at the standard data sites. When this Form with Standard Hidden Elements sends input, you decrypt the information, setup the login information, and handle the other tasks as in the standard login form.
We have worked with Forms, but now we must handle Anchors. For Sapphire/Web there will be two types of anchors: Hotlist with a bound anchor, and all other bound anchors. Consider first the hotlist with a bound anchor. With the encrypted password, you store the encrypted information as keyed strings with the function, SaStoreKeyString. The login function uses the standard keys: EUSER and EPASS. Once this is done, the standard Hotlist Population Calls, SaPopulateHotList and SaPopulateMasDetHotList, will automatically place these keyed strings and their values in the Anchors. These keyed strings will be available when the anchor calls the CGI, and are retrieved with the function, SaGetKeyedArg. Once the login function determines that this is an Anchor to the activator, it retrieves the encrypted information and the rest is handled in exactly the same way as the Form with hidden elements.
One last case must be considered; storing keyed strings in a bound anchor which is not populated with the two population calls above. The solution is found in the third html file, saAuthorDetail.html. Notice the Data Site before the Anchor. This data site has a standard name, "COOKIE". You need to mark up these remaining types of anchors with this standard Data Site. To handle this, the login function registers a Data Site Callback Function for this standard site. The registered function is built into the Sapphire/Web API, SaPrintAllKeys. This function appends all stored keys into the anchor string.
Username:
<INPUT TYPE="text" NAME="USERNAME">
Password:
<INPUT TYPE="password" NAME="PASSWORD">
n summary, to achieve maintaining login information, do the following. Use the login functionality in saSetupLogin.c. You must change the encryption and decryption routines. For all login forms use these 2 input elements:
For all other forms use these 2 hidden elements:
<INPUT TYPE="hidden" NAME="EUSERNAME" VALUE="##Sa_EUserName##">
<INPUT TYPE="hidden" NAME="EPASSWORD" VALUE="##Sa_EPassWord##">
For all bound anchors (except those to be hotlist) add the data site as in the following example:
##Sa_COOKIE##<A HREF="AuthorList">List of Authors</A>You can change all these names to your own standard names, but you must change the variables in the login function. You may wish to use a similar design for maintaining other state information. To use a keyed string as a cookie value instead of encrypted login information, another options is to store the login information on your server. Sapphire/Web does not perform cookie storage on the server side.