Wednesday, July 30, 2008

Email Verification using c#

One thing that's really common is to require email verification before letting a new user into the system. The CreateUserWizard by default doesn't work that way, basically after user registration is done you are logged in automatically (if LoginCreatedUser=true) or if false then the user just needs to login.

As we have decided email is the central point here - working as the username, let's implement email verification before newly created users can login.

It should work this way - after the user has registered he/she should be told something like "Thanks for registration. Now wait for an email and click the link for verification, after that you have access to our site".

First, inside the CreateUserWizard, create a CompleteWizardStep template:





Thanks for registering with us

Now wait for an email to be sent to the email address you specified with instructions to enable your account and login.



Now set LoginCreatedUser="False" and DisableCreatedUser="True" for the CreateUserWizard.

This will create the user as disabled and the idea is to send the user an email containing an unique verification url which when clicked sets the user account to approved (oUser.IsApproved = true;)

In CreatedUser event we are supposed to send an email:


protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
CreateUserWizard cuw = (CreateUserWizard)sender;
MembershipUser user = Membership.GetUser(cuw.UserName);
Guid userId = (Guid)user.ProviderUserKey;
string sHeader = "";
string sBody = "";
MailHelper.NewUserMail(userId.ToString(), ref sHeader, ref sBody);
MyContext.SendEmail(cuw.Email,
sHeader,sBody, true);
}



I am using some helper functions but the basic idea is that all users gets a unique id from the provider - and for SQL Server it's a guid, which is guaranteed to be unique and also to hard to guess for an outsider. So I retrieve that value for the newly created user through user.ProviderUserKey and use that to build up a registration url string in the email:

To give you the idea the string will be

http://www.aspcode.net/blabla/activate.aspx?id=

We send an email to the user containing that string and when they click on it they go to our page activate.aspx:

In Page_Load we simply retrieve the id and approve it:


Guid oGuid = new Guid(sKey);
MembershipUser oUser = Membership.GetUser(oGuid);
if (oUser != null && oUser.IsApproved == false )
{
oUser.IsApproved = true;
Membership.UpdateUser(oUser);
System.Web.Security.FormsAuthentication.RedirectFromLoginPage(oUser.UserName,
false);
}



Last, the verification cheme is pretty lame I know, but it might be good enough. Some improvements would be to also require the email address, which would force the user to also enter the email adrress (mimimizes guid guessing risks), and of course the code to just use user.ProviderUserKey is not very smart - it works for SQL Server but there is a risk some other provider just implements it as a autonumber field - i.e just a sequencial number, very easy to guess. You could of course add your own guid generation, storing it somewhere else - tying it with the user.ProviderUserKey.


Regards,


Ujjwal B Soni

+919998971048

No comments: