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
developerWorks - FREE Tools! |
<a href="http://zeus.developershed.com/shonuff.php?blackbird=3853&zoneid=442&source=&dest=http%3A%2F%2Fwww.ibm.com%2Fdeveloperworks%2Fspaces%2Fjazz%3FS_TACT%3D105AGY31%26S_CMP%3DDEVSHED&ismap="><img src="http://images.devshed.com/corp/img/news/jazz01.gif" alt="developerWorks Jazz space" align="left"></a>You've heard the buzz about Jazz... want to know more about it from a developer's perspective? Check out the Jazz space on developerWorks. This space is an up-to-date resource for developers, including technical information about Jazz and products built on Jazz, like Rational Team Concert Express. The Jazz space includes content from a wide variety of sources, including links, feeds, and comments from experts. FREE! Go There Now!
|
|
|
|
Learn field-tested SOA principles, methodology, technology and implementation from the global SOA market leader - in a new e-book by an IBM SOA expert. Written by IBM Certified SOA Solution Designer Bobby Woolf, "Exploring IBM SOA Technology & Practice" is the ultimate insider's guide to SOA - a PDF e-book packed cover to cover with IBM's specific advice on how to make your SOA implementation a success. FREE! Go There Now!
|
|
|
|
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!
|
|
|
|
Download a free trial version of IBM DB2 9.5 for Linux, UNIX, and Windows. DB2 9 is the result of a five-year development project that transformed traditional (static) database technology into an interactive data server that merges the high performance and ease of use of DB2 with the self-describing benefits of XML. FREE! Go There Now!
|
|
|
|
Join us for this web seminar to learn how you can defend your web applications from attack. Learn about the 3 most common web application attacks, including how they occur and what can be done to prevent them. We’ll also discuss manual versus automated approaches for scanning and identifying web application vulnerabilities and how IBM Rational AppScan, an automated vulnerability scanner, can help you automate more of what you are doing manually today. FREE! Go There Now!
|
|
|
|
This tutorial shows new users of IBM WebSphere Business Monitor Version 6.0.2 how to perform the "Hello World" equivalent for monitoring business process applications. It is intended to help you get familiar with the capabilities of the product. FREE! Go There Now!
|
|
|
|
Analysts, architects, and developers who have existing COBOL or PL/I skills and want to extend those skills to deploy new workloads on the mainframe can use the IBM Enterprise Modernization Sandbox for System z to find hands-on walkthroughs of common real world scenarios. The scenarios provide examples of how to rapidly design, create, assemble, test, and deploy high-quality Web, Web services, portal, and SOA applications for IBM CICS, IBM IMS, and IBM WebSphere Application Server. FREE! Go There Now!
|
|
|
|
Learn from the best! Find out how developers use Rational ClearCase to be more flexible, innovative and deliver higher quality code in the Rational ClearCase Power Users eKit. This complimentary eKit provides a collection of materials, like articles, whitepapers, and demos that can help you become a power user of Rational ClearCase. FREE! Go There Now!
|
|
|
|
Attend this launch webcast with Scott Hebner, Vice President of IBM Rational Marketing and Strategy, where he will overview Rational’s new offerings and programs to help customers accelerate software innovation on System z. He will discuss how these solutions help organizations extend their core business processes toward modern architectures such as SOA and web technologies to deliver business improvements that stand the test of time. FREE! Go There Now!
|
|
|
|
With IBM Rational Systems Development Solution, you can deliver products faster with higher quality. Within this kit, Read the “Model Driven Systems Development” white paper to see how to improve product quality and communication. Then check out the rest of the e-Kit to learn more about important topics that can affect the success of any software project through customer examples, tutorials, informative Webcasts, and best practices for designing, building and managing systems. From start to finish, at every stage in your projects, Rational Systems Development Solution can help your company reach its full potential. FREE! Go There Now!
|
|
|
|
All FREE IBM® developerWorks Tools! |