Home arrow IIS arrow Page 3 - An Introduction To ISAPI
IIS

An Introduction To ISAPI


ISAPI extensions allow you to access the operating system on your web server (including API calls) while still communicating with your web site through the response object. In this article Raj gives us a nice introduction to ISAPI and also shows us two examples that he's made with Delphi and Paradox. The examples implement a simple login system and utilize a database. Even if you don't know Deplhi then you'll still be able to pick up the basics of ISAPI in a flash!

Author Info:
By: Raj Bakhru
Rating: 4 stars4 stars4 stars4 stars4 stars / 25
April 11, 2002
TABLE OF CONTENTS:
  1. · An Introduction To ISAPI
  2. · The Benefits of ISAPI
  3. · ISAPI Database Example
  4. · Conclusion

print this article
SEARCH DEVARTICLES

An Introduction To ISAPI - ISAPI Database Example
(Page 3 of 4 )

Before beginning our database application, we need a database to access. I've included a copy of the database I'll be using in this example with the source code for this article. If you like, you can create this database yourself or you can just follow along with this tutorial. The database is a Paradox 7 database named "users.db". It contains the following fields: "User", "Password", "Special Comments", and "Key". All four fields are strings. We must also create an "alias" in the BDE for this database. I named mine "ISAPI_Example". (NOTE: Delphi comes with a tool to assist in creating databases: Database Desktop. Within this application, itís very easy to create a database and then define the fields for that database).

Like in our previous example, we create our new project from File->New Project->Other...->ISAPI/NSAPI Dynamic Link Library. Our WebModule loads and we can begin altering the application. The simple ISAPI extension we'll make is one that, when called, provides a login form which submits to another action called "PostLogin". After submission, it checks the login information against the database, and if the data matches it outputs the "Special Comments" field for that user. On a successful login, the "key" field of the database will be edited to include a randomly generated number. Two cookies will then be set, one for the "username" value and the other for the "key" value.

This will allow the user to access other areas of the site without having to log back in every time. Our main login form will check for the cookies, and, if they exist and are correct, the user will then be directed to the post-login page. Another function, logoff, will delete the cookies.

Before defining our functions, we should create our TTable component - this will allow for our database access. We create an instance of this component in the WebModule. We then define the properties: Name = UsersDB, DatabaseName = Users (or whatever you named your alias), TableName = users.db, Active = false.

The following actions/functions will be included (as described above):
  • Login (Default)
  • PostLogin
  • Main
  • Logoff
The first function, login, is set as follows:

procedure TWebModule1.WebModule1LoginAction(Sender: TObject;

Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

begin

UsersDB.active := true; //Table must be active for use

//This will output the login form

response.content := '<html><head><title>Login</title></head><h3>Login</h3>'

+ '<form name="login" action="' + request.ScriptName + '/postlogin" method="post">'

+ 'Username: <input type="text" name="user"><br>Password: <input type="password" name="password">'

+ '<p><input type="submit" value="Login"></form></html>';

//The following if clause will check if the user is logged in, if so, they'll be

//forwarded to the "main" page. The redirect can override the content from above.

if request.CookieFields.values['user'] <> '' then //Check for user cookie

begin

UsersDB.Filter := '(user = ''' + request.cookiefields.values['user'] + ''')';

UsersDB.Filtered := true;

if UsersDB.fieldbyname('key').asstring = request.CookieFields.values['key'] then

response.sendredirect(request.ScriptName + '/main'); //This will override the content from response.content

end;

UsersDB.Active := false; //Always be sure to stop the database to avoid errors/corruption.

end;


We now need to create our login handler, PostLogin. It must first check to see whether the method called is "POST". It must then check the information. The code below accomplishes this task. Upon a successful login, it forwards the user to the "Main" page with some JavaScript. The reason we use JavaScript to forward the user is because if we use a standard request.sendredirect, then the cookies will not be sent/set.

procedure TWebModule1.WebModule1PostLoginAction(Sender: TObject;

Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

var authenticated: boolean; //This will hold whether authentication was valid or not

begin

UsersDB.Active := true;

//Default the authenticated value to "not-valid".

authenticated := false;

//Check the method for POST and make sure the values aren't blank...

if (request.method='POST') and (request.ContentFields.values['user'] <> '') and (request.contentfields.values['password'] <> '') then

begin

UsersDB.Filter := '(user = ''' + request.contentfields.values['user'] + ''') and (password = ''' + request.contentfields.values['password'] + ''')';

UsersDB.Filtered := true;

if UsersDB.RecordCount = 1 then

authenticated := true;

end;

//If not authenticated, output an error; if authenticated, send the user to "main" and set the cookies.

if authenticated = false then

response.content := '<html><head><title>Error!</title></head><h3>Error!</h3><hr>There was an error processing your login!</html>'

else

begin

// If valid, set the cookies

with response.cookies.add do

begin

name := 'user';

value := request.contentfields.values['user']

end;

randomize(); //allows for use of the random() function

//Create a random "key" session variable.

UsersDB.edit;

UsersDB.fieldbyname('key').asstring := IntToStr(random(999999));

UsersDB.post;

//Set the "Key" cookie that will be checked against the database

with response.cookies.add do

begin

name := 'key';

value := UsersDB.fieldbyname('key').asstring;

end;

//Forward to the main page

response.content := '<script language="JavaScript">document.location.href="' + request.scriptname + '/main";</script>';

end;

UsersDB.Active := false;

end;


The next step is to create the "Main" action. It'll first check the authentication based on the cookies and the "key" value in the database. Then, if the authentication passed, it will output the "Special Comments" field from the database and include a link to "Logoff". Here's our definition for the "Main" action:

procedure TWebModule1.WebModule1MainAction(Sender: TObject;

Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

var authenticated: boolean;

begin

//Default our authentication value to false.

authenticated := false;

//Start the database and set the filter to the cookie values. If the database checks

//against the cookies, set authenticated to true. Otherwise send the login page.

UsersDB.Active := true;

UsersDB.filter := '(user = ''' + request.cookiefields.values['user'] + ''') and (key = ''' + request.cookiefields.values['key'] + ''')';

UsersDB.filtered := true;

if UsersDB.recordcount = 1 then

begin

authenticated := true;

end

else

begin

//If not authenticated, send them to the login page.

response.sendredirect('login');

end;

//Send the main page if authenticated properly.

if authenticated = true then

begin

response.content := '<html><head><title>Welcome</title></head><h3>Welcome<hr><strong>Welcome ' + usersdb.fieldbyname('user').asstring + ',</strong><br>'

+ '<i>Special Comments</i><br>' + usersdb.fieldbyname('special comments').asstring + '<p><a href="logoff">Logoff</a></html>';

end;

UsersDB.active := false;

end;


And finally, we define the logoff action:

procedure TWebModule1.WebModule1LogoffAction(Sender: TObject;

Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

begin

//To delete cookies, set the expiration date to the past.

with response.cookies.add do

begin

name := 'user';

value := '';

expires := Now-1; //Expires Yesterday :)

end;

with response.cookies.add do

begin

name := 'user';

value := '';

expires := Now-1; //Expires Yesterday :)

end;

//Use JavaScript to forward to the login page. Remember - we can't use response.sendredirect because

//the cookies will not register then...

response.content := '<script language="JavaScript">document.location.href="login";</script>';

UsersDB.active := false;

end;


This basically provides the entire application. The reason I've provided the source code rather than just outlining it is because you can follow along using the comments in the source code to help you understand what's going on at various points throughout our ISAPI application. To see a working version of this application, click here. You can login with tue username Guest and password Guest.

Here's how it looked for me:

The ISAPI's login screen

Once I have logged in
blog comments powered by Disqus
IIS ARTICLES

- Beefing Up IIS: 10 Tips From A Former Solari...
- An Introduction To ISAPI
- Secure Your Web Server With SSL

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials