ASP.NET 3.5 Social Networking
上QQ阅读APP看书,第一时间看更新

Design

In this section, we will discuss the various aspects that are required to implement our new features. Once we are finished, we should have a good idea of what will be required from each area.

Registration

Registration includes the task of acquiring user information, allowing them to pick a username, password, and email verification. In addition, we will require that our users agree to our terms and provide verification that they are human and not a bot by reading our CAPTCHA image. Once we have all this information, we will create the user account and assign appropriate permissions to the account.

Accounts

While ASP.NET provides various pre-built tools for handling your users via the membership controls, I have decided to explore a custom way to handle our users with regards to logging them in, encrypting their passwords, and so on. You may ask why I decided to go this route. It's simple really; everyone has contributed a number of webpages and blog posts to the Internet as well as written a number of books regarding this topic. It seemed reasonable to me then that perhaps people might like to see if they can do it on their own. It's not that difficult really! Also, with custom logic comes more control.

To begin with, we need a way to describe our accounts. From the database point of view, it will be fairly simple. All we need is an "Accounts" table where we can hold a username, password, and a few other bits of information. This will look something like this:

Accounts

Note

While most of this information looks fairly normal (FirstName, LastName, Email, and so on), there are a few columns that may not make sense at first. You will see that I have added a Timestamp field to just about every table. This is important for smoothening your interaction with LINQ. While it is not required by LINQ, I find that LINQ works much better with it in place, when tracking changes across disconnected data contexts.

Password strength

Password strength is not only an issue for the account's security but also for the site owner. The weaker your user's password is, the more likely that someone performs a brute force attack on your site. If an account with a high-level permission (such as Administrator) is compromised due to a weak password, you will look pretty silly! It doesn't make much sense on your part to create a secure site in every other way and then allow your users to bypass all your efforts!

Having said that, forcing your users to have a strong password can become an inconvenience to your users. Believe it or not, there are many users who would prefer to have a password of "password". While I am not for letting your users become lazy, you do need to be aware that there is a chance that you will lose signups due to this requirement. It is up to you to decide how important a secure site is!

Terms and conditions

While terms and conditions are not a necessary requirement for a good site, this section is the place to cover the concept! We will create a simple way to manage your terms and conditions. Terms and Conditions are a legal thing. The legal aspect is not my strong suite, but building a system to house them is! Knowing that terms and conditions can change over time, it is important that you track which version of terms and conditions your users last agreed to. It is also important that you track when they agreed to them.

The database will look something like this:

Terms and conditions

CAPTCHA

CAPTCHA, or Completely Automated Public Turing test to tell Computers and Humans Apart, is a form of challenge-response test to determine if the user of your site is a computer or human. Increasingly we are finding that people are writing bots to inject advertisements and other forms of SPAM into community sites to capitalize on the traffic of those sites. The bots sign up for an account, verify their emails, and start posting ads to our forums, blog comments, and so on. Hence we need a way to determine if the person registering for an account is a computer or a real human.

A CAPTCHA system does a fairly good job of determining this. These systems generate an image with an imbedded string that the registrant needs to read and copy into a text field. As there are currently no good algorithms for reading the obfuscated text out of the distorted image, we can feel pretty confident that the entity that is registering for an account is a human.

Here is an example of an image that will be generated by our system:

CAPTCHA

While our system could be very complicated, we will stick to a simple random number for our CAPTCHA string. Some systems use a table of words and present two words randomly paired. Either of these ways will work well enough, and random numbers are easily handled by .NET already.

Email confirmation and verification

There are several reasons to use email communications in our community. For example, this chapter will require registration confirmation and email validation.

When a user signs up at our site, we need to be able to let him/her know that the registration was completed successfully. This email will usually welcome a user to the site. It may also provide them with some frequently asked questions, a list of benefits received upon registration, and any other pertinent information that a user may need prior to using your site.

In addition to the registration receipt, we need a way to check whether the email address that the user has provided is a valid account (that it actually exists), and one to which the user actually has access. We will validate this by embedding a link in the email that the user will have to click. Once this link is clicked, we will assume that the email address is valid!

Security

Security is obviously one of the most important aspects of building a site. Not only should you be able to provide access to certain areas of your site to specific people, but more importantly, also be able to deny access to various people of your site. All sites have areas that need to be locked down. For example, one of the most important areas could be the administration section of your site, or paid areas of your site. Therefore, it is very important to make sure that you have some form of security.

Permissions

There are a number of ways to handle permissions. We could make something really complex by implementing a permission based system using permissions, roles, groups, and so on. We could even make it as complex as Microsoft's Active Directory system. However, I find that keeping something only as complex as your current requirement is the best thing to do. We can always add to the system as our needs increase.

Our permissions system will simply encompass a name (Administrator, Editor, Restricted, and so on). This permission name will then be statically mapped to each page (using the Sitemap file that .NET provides us!). As long as we keep our pages to serve a single functionality, this should always suit our needs. As this is a good design practice anyway, we shouldn't have any problems here. Of course, a user can have many permissions tied to their accounts so that they can traverse various sections of our site. Once this is in place, all we need to do is have a system that checks a user's permissions upon entering each page to ensure that they have the permission that the page requires.

The database structure for this will look like this:

Permissions

We will have a Permissions table, which relates to the Accounts table through the AccountPermissions table. This is a pretty straightforward and simple design.

Password encryption/decryption

While we could easily store a user's password in our database as plain text, it would not be a very responsible thing to do! Having a password stored in plain text not only leaves your user accounts open to someone who might hack into your system or database but also leaves them open to a possible attack from a disgruntled employee. These are good enough reasons to encrypt passwords prior to storing them in the database.

There is still an issue to discuss though. Do we have one way encryption, or do we also provide a way to decrypt our encrypted passwords? If we don't provide decryption facilities, then we won't be able to send reminder emails to our users who have their passwords. If we were creating a banking system, sending passwords via email would not be acceptable. However, as we are creating something slightly less confidential, the convenience for users to be able to retrieve their passwords without too much hassle is a great reason for decrypting the password and sending it to the user.

Logging in

Once a user has created an account, it is important for them to be able to re-identify themselves to us. For this reason, we will need to provide a way for them to do this. This will come in the form of a page that accepts a username and a password. Once they have authenticated themselves to us, we will need to make sure that they are still allowed to get into our site (if they are valid users).

Password reminder

A user will inevitably forget his/her password. As we require a strong password, and a fair number of users would rather not have a password at all, or would like to use the word "password' as their password, it is highly possible that they forget what they registered with. Not a problem! As we decided to use a two-way encryption, we will be able to decrypt their chosen password and email it to them. This way, our user will never be locked out for too long!

Manage account

In order to keep customer service calls to a minimum, we will need a way for our customers to manage their own accounts. Our customers will need a way to update most of the information they provide us. While we will not allow them to change their username, we will allow them to edit the rest. And when we allow them to change their email address we need to make sure that we force them to validate their new address.