ASP
  Home arrow ASP arrow Adding Member Services in ASP
Iron Speed
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  
Download TestComplete 
IBM® developerWorks 
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? 
ASP

Adding Member Services in ASP
By: James Shaw
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 13
    2003-05-09

    Table of Contents:

    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
     
     
    Iron Speed
     
    ADVERTISEMENT

    TestComplete™ automates software testing for a fraction of what the big guys charge. Easy functional and load testing for all Windows, .NET, Java and Web apps. Download a free trial now.

    What to add member services to your site? James will explain how this is done using ASP so that your members can obtain different privileges.

    Implementing a membership system for CoverYourASP was simple in concept, but ended up touching a lot of pages, and created 10 new ones!

    Here's what I wanted, and got, from my system - I'll go through each one in the following pages:

    • Members can register themselves via a form.
    • Validation of membership changes via email.
    • Sign in/out using users email address and password.
    • Option to sign in automatically using a cookie (low security).
    • Ability to send password to members who forget.
    • Multiple levels of membership with more functionality.
    • Free Bronze membership has database storage of site personalization.
    • Easy upgrade to higher membership level using PayPal.
    • Members-only area available only to Silver members.
    • Registering new members
    • Registering a new user requires a straightforward form that adds a new record to the database.

    You can view the real source code here, but before you do, I should tell you that the same form is also used to edit existing member information too.

    A simple call to IsLoggedIn ( ) - a function defined in the utils/Login.asp file - allows me to tell which task I'm undertaking with the form. It also controls what action I'm taking in the database, as the excerpt below shows:

    // connect to the database
    DBInitConnection ( );
    if ( IsLoggedIn ( ) )
    {
       // update the member information
       oConnection.Execute ( 'UPDATE Members SET Name=\'' + sName + '\',Email=\'' + sEmail + '\',MemberPassword=\'' + sPassword1 + '\' WHERE MemberID=' + nMemberID );
    }
    else
    {
       // create the new member record
       oConnection.Execute ( 'INSERT INTO Members (Name,Email,MemberPassword) VALUES ("' + sName + '","' + sEmail + '","' + sPassword1 + '");' );
    }
    // release the database
    DBReleaseConnection ( );

    Having added the new member to the database, there is one more step the user must take before he can sign in...

    Email Validation of Membership Changes

    I wanted to validate the creation and deletion of members via email, and I wanted it to be automatic. A simple email to me wasn't good enough, but I didn't want to develop an application that listened to email coming in either.

    I compromised by sending the member an email that contained a link to a new confirm page, named C.asp. The user has to click on the link (if their email client supports that), or cut/paste the link into their browser.

    The email I send to confirm a new user was created with this code:

    // send Email with our generic function
    var sBody = 'Dear ' + sName + '\n\n';
    sBody += 'To complete the registration of your CoverYourASP membership account please click on the link below, or copy and paste the entire URL into your browser.\n\n';
    sBody += 'http://CoverYourASP.com/C.asp?a=a&e=' + sEmail + '&i=' + nID + '\n\n';
    sBody += 'Regards,\n';
    sBody +=
    'MemberServices@CoverYourASP.com\n'
    ;
    sBody += 'http://CoverYourASP.com/';
    SendEmail ( 'MemberServices@'
    + sHostDomain, sEmail, '', 'New membership', sBody );

    This generates an email that contains this line:

    http://CoverYourASP.com/C.asp?a=a&e=test@coveryourasp.com&i=7

    (Note: Many email clients will suffer from a "wrap" problem, meaning the hyperlink they show will only include the part of the URL on the first line. In this case the user must use the cut/paste method to use the entire URL)

    C.asp in turn has the following code to decode that URL and perform the task of setting the Confirmed flag in the member record.

    var sAction = '' + Request.QueryString ( 'a' );
    var sEmail = '' + Request.QueryString ( 'e' );
    var nID = Request.QueryString ( 'i' ) - 0;
    switch ( sAction )
    {
    case 'a':
       DBInitConnection ( );
       // set the confirmed status on the membership
       oConnection.Execute ( 'UPDATE Members SET Confirmed=1 WHERE MemberID=' + nID + ' AND Email="' + sEmail + '"' );
       DBReleaseConnection ( );

    One last note - C.asp doesn't bother reporting if the parameters given were invalid. If the Email doesn't match the given ID then the database won't be modified thanks to the SQL statement used.

    Signing In and Out

    The sign in process starts with a call to ShowLoginStatus( ) in utils/Header.asp. The ShowLoginStatus function contains the following code:

    if ( IsLoggedIn ( ) )
       Out ( '<a href="MemberLogout.asp">Sign out</a> ' + sMemberName );
    else
       Out ( 'Join in the fun! <a href="MemberLogin.asp">Sign in</a>' );

    This will be the first call to IsLoggedIn( ), which first checks if the function has already been called on this page (if bLoggedIn is undefined), then checks if the Session has been signed in.

    Every visitor gets assigned a unique session - Session variables like this are available to every page on your web site, and allow you to store data that is unique to each visitor.

    If signed in then some other global variables are assigned from the current Session - this just makes it less expensive to access this data later in the page.

    if ( bLoggedIn == undefined )
    {
        bLoggedIn = Session ( 'Authenticated' );
       if ( bLoggedIn )
       {
          sMemberName = Session ( 'MemberName' );
          sMemberEmail = Session ( 'MemberEmail' );
          nMemberID = Session ( 'MemberID' );
          nMemberLevel = Session ( 'MemberLevel' );
       }
    }
    return bLoggedIn;

    Back in ShowLoginStatus( ), the user is either shown an option to sign in, or sign out. Signing in is done with a simple form asking for the member email and password. The ValidateLogin( ) function is then called when the form is submitted. Let's look at the ValidateLogin( ) function:

    // connect to database
    DBInitConnection ( );
    // search for matching email/password
    DBGetRecords ( 'SELECT MemberID,Name,MemberLevel FROM Members WHERE Confirmed=True AND Email=\''+sEmail+ '\' AND MemberPassword=\'' +sPassword+ '\'' );
    if ( !oRecordSet.EOF )
    {
       Session ( 'MemberEmail' ) = sEmail;
       Session ( 'MemberID' ) = oRecordSet ( 0 ) - 0;
       Session ( 'MemberName' ) = '' + oRecordSet ( 1 );
       Session ( 'MemberLevel' ) = oRecordSet ( 2 ) - 0;
       Session ( 'Authenticated' ) = 1;
    }
    // release database
    DBReleaseConnection ( );

    So the database is searched for a matching email/password. If found the Session variables are initialized to the correct values, and the visitor is "signed in"!

    Signing a member out is a little easier! A call to Logout( ) in utils/Login.asp contains this code:

    // clear the authenticated status
    Session ( 'Authenticated' ) = 0;

    Big Important Note: Before I leave the subject of signing in, you should be aware that my implementation is NOT SECURE. Password information over a normal HTTP connection can be seen by anyone. On my site this isn't important, but remember to send important information via HTTPS in real life.

    Forgotten Passwords

    Sending passwords via email was very simple, although, yet again, a little unsecure. A form asks for the members email address, looks that up in the database and emails the password.
    Here's the "essence" of the code that does all that:

    DBInitConnection ( );
    DBGetRecords ( 'SELECT Name,MemberPassword FROM Members WHERE Email=\'' + sEmail + '\'' );
    if ( !oRecordSet.EOF )
    {
       // get data from recordset
       sName = '' + oRecordSet ( 0 );
       sPassword = '' + oRecordSet ( 1 );
       var sBody = 'Dear ' + sName + '\n\n';
       sBody += 'Your password is: ' + sPassword+ '\n\n';
       sBody += 'Regards,\n';
       sBody +=
    'MemberServices@CoverYourASP.com\n'
    ;
       // send Email with our generic function
       SendEmail (
    'MemberServices@'
    + sHostDomain, sEmail, '', 'Lost Password', sBody );
    }
    // release the database connection ASAP
    DBReleaseConnection ( );
     
    Creating levels of membership was trivial - I just added a new field to my table called... no, I should make you guess!
    Another Session variable and global variable and I can now write code to test against membership level:

    // are they a high enough level?
    if ( nMemberLevel < nLevel )
    {
       // no, let them know
       Out ( 'You need to upgrade your membership to ' + sLevels [ nLevel - 1] + ' - you are a ' + sLevels [ nMemberLevel - 1 ] + ' member.' );
    }
    else
    {
       // valuable content goes here!
    }

    Free Site Personalization

    Through a simple form you can change settings that control how the front page is displayed.

    The only fun part of this was that I had to calculate how many books and banners to display down the side of a page - you can basically turn everything off! Here's the code I used:

    // I have to calculate how many banners now
    var nBanners = 1;
    if ( bIntro )
       nBanners++;
    if ( bSuggestions )
       nBanners++;
    if ( bDiary )
       nBanners++;
    if ( nNew || nPopular )
       nBanners +=  Math.floor ( (nNew + nPopular) / 2.5 );
    if ( bCategories )
       nBanners += 3;
    if ( bNews )
       nBanners++;
    // show rotating banners
    ShowBanners ( nBanners?nBanners:1 );

    Currently you can hide/show the introductory text at the top, the categories and ASPWire news. You can also specify the number of articles in the New and Most Popular sections. Set to zero, and those sections disappear too!

    Further plans? You tell me what you want, but I suspect that using my Yahoo-style category layout may be an option. It seems like I nearly have enough content to justify it!

    Upgrade Membership

    Ugrading membership, and how I used PayPal to accept payment are the subject of a separate article, to be published soon.

    Members-only Area

    Providing a members-only area required very little code. First I created a function in Login.asp:

    // ============================================
    // make sure the user is signed in, and has sufficient access rights
    // if not then redirect to passed in page
    // ============================================
    function NeedAccessLevel ( nLevel, sRedirect )
    {
       if ( !IsLoggedIn ( ) )
          Redirect ( 'MemberLogin.asp' );
       if ( nMemberLevel < nLevel )
          Redirect ( sRedirect );
    }

    The function takes two parameters - the level required and a page to redirect to if the members level is lower than necessary.

    Here's how I use it in the exclusive member-only pages - add this code to the top of the page, before the call to Init(), in case the function redirects the user:

    // need signed in members of level 2 and above
    NeedAccessLevel ( 2, 'MemberUpgrade.asp' );


    DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

    More ASP Articles
    More By James Shaw

     

    IBM® developerWorks developerWorks - FREE Tools!


    IBM – Taking Web 2.0 to Work

    You'll get answers to many questions and more from David Barnes, Lead Evangelist for IBM Emerging Internet Technologies. David will discuss aspects of Web 2.0 that bring value to corporations, academia, and government. He'll also discuss IBM's vision around Web 2.0, including the importance of remixability and consumability. The discussion will culminate with examples of various IBM Software Group solutions you can use to get ahead of the Web 2.0 adoption curve.
    FREE! Go There Now!


    NEW! Addressing software-as-a-service challenges using Tivoli security and WebSphere solutions

    Building a software-as-a-service solution requires addressing a few key technical challenges. In this webcast, we'll focus on the role of IBM Tivoli Directory Server and WebSphere Portlet Factory in creating a Software as a Service solution. We will demonstrate how to use Tivoli Directory Server to prevent the user population of one tenant from accessing the virtual portal and portlet components of another tenant. We will also use the dynamic profile capability of WebSphere Portlet Factory to create multiple highly customized applications from one code base.
    FREE! Go There Now!


    NEW! Build Web services with transport-level security using Rational Application Developer V7, Part 1: Build Web services and Web services clients

    Build secure Web services with transport-level security using IBM Rational Application Developer V7 and IBM WebSphere Application Server V6.1. Follow this three-part series for step-by-step instructions about how to develop Web services and clients, configure HTTP basic authentication, and configure HTTP over SSL (HTTPS). This first part of the series walks you through building a Web service for a simple calculator application. You generate and test two different types of Web services clients: a Java Platform, Enterprise Edition (Java EE) client and a stand-alone Java client. You also handle user-defined exceptions in Web services.
    FREE! Go There Now!


    NEW! Develop with Java and PHP technology on AIX Version 5.3, Part 6: Building the Java business application

    Set up a PHP Web interface for the Java(TM) business application using a database created in earlier in this series. The PHP Web interface collects information from users and sends the session data to the Java business application for processing and for a response.
    FREE! Go There Now!


    NEW! Push RSS to new limits

    This tutorial presents an innovative use of the well-known Really Simple Syndication (RSS) format's associative properties to emulate the functionality of a simple relational database. It demonstrates using RSS channels to store contact information and meeting information -- much as a personal address book and calendar does. It uses RSS elements and attributes such as items and guids to create a neural-network-like mesh of related data.
    FREE! Go There Now!


    NEW! Rational Talks to You: Manage RUP-based CMMI initiatives

    Join this Rational Talks to You teleconference on December 4 at 1:00 pm ET to discuss how Rational Method Composer can help meet your compliance objectives. Get your questions answered!
    FREE! Go There Now!


    NEW! Rational Testing eKits

    Discover how Rational tools and best practices for testing can make your job easier. The new Rational Testing eKits provide you with valuable resources – including demos, webcasts, tutorials, and articles – that help you address your specific testing needs across the software lifecycle. Five new eKits are available covering the topics of Requirements and Test Management, Functional Testing, Performance Testing, Code Quality and Embedded Systems, and SOA and Web Services Testing.
    FREE! Go There Now!


    NEW! Web development with Eclipse Europa, Part 1: The Java EE for Eclipse

    It's a good time to be a Web developer. You've never had more choices in terms of technologies. There are so many great open source Web servers, databases, programming languages, and development frameworks. No matter what combination of technologies you prefer to work with, there is an integrated development environment (IDE) that can increase your productivity: Eclipse. In this tutorial, Part 1 of a three-part "Web development with Eclipse Europa" series on how to use Eclipse for Web development with Java technology, PHP, and Ruby, we'll see how the latest release of Eclipse -- Europa -- can be used to rapidly develop Java Web applications. We'll use Java Platform, Enterprise Edition 5 (Java EE) for Eclipse to build a Web application for tracking and calculating baseball statistics.
    FREE! Go There Now!


    NEW! Webcast: Calling All Testers! Find Application Vulnerabilities Early in the Development Process Where they are Easier to Fix and Less Risky to your Business

    In this webcast, IBM Rational will discuss the importance of Web application security and will share techniques and best practices to introduce application security testing into current QA processes including: understanding common security vulnerabilities and techniques to integrate security testing with defect tracking and remediation systems in an effort to safeguard sensitive online information.
    FREE! Go There Now!


    NEW! Webcast: Introducing the new Information Server and Solutions community: LeverageInformation

    User communities play an important role in communication and collaboration around products, solutions and other areas of special interest to members. Successful communities are able to provide the right mix of content and services to deliver a value proposition that resonates with each audience. Join Tom Inman, VP of Marketing for Information and Platform Solutions as he introduces the new LeverageINFORMATION community. During this webcast, learn about the value provided by the community and how customers and partners derive value from the community in addressing their own technical and business challenges.
    FREE! Go There Now!



    All FREE IBM® developerWorks Tools!

    ASP ARTICLES

    - Central Scoreboard with Flash and ASP
    - Calorie Counter Using WAP and ASP
    - Creating PGP-Encrypted E-Mails Using ASP
    - Be My Guest in ASP
    - Session Replacement in ASP
    - Securing ASP Data Access Credentials Using t...
    - The Not So Ordinary Address Book
    - Adding and Displaying Data Easily via ASP an...
    - Sending Email From a Form in ASP
    - Adding Member Services in ASP
    - Removing Unconfirmed Members
    - Trapping HTTP 500.100 - Internal Server Error
    - So Many Rows, So Little Time! - Case Study
    - XDO: An XML Engine Class for Classic ASP
    - Credit Card Fraud Prevention Using ASP and C...






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