SunQuest
 
       IIS
  Home arrow IIS arrow Page 3 - An Introduction To ISAPI
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Dedicated Servers  
Actuate Whitepapers 
VeriSign Whitepapers 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
IIS

An Introduction To ISAPI
By: Raj Bakhru
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 18
    2002-04-11

    Table of Contents:
  • An Introduction To ISAPI
  • The Benefits of ISAPI
  • ISAPI Database Example
  • Conclusion

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT

    Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here

    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

    More IIS Articles
    More By Raj Bakhru


     

    IIS ARTICLES

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







    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway