ASP.NET专题研究——用户登录、注册和发送密码

在“权限登录”一篇中我们介绍了如何使用微软最新的权限特性,通过在配置文件中声明简单的权限可以达到控制登录用户和匿名用户的目的,同时还教会大家如何使用Login控件的Authentication事件进行登录。但是,事件中的验证代码还是需要你来完成的。作为快速开发的VS IDE,微软有没有为我们提供更简单的方法呢?答案是“有的”。今天就给出一个完整的,几乎不用编写任何代码的简单登录、注册和密码遗忘的功能的页面。同时为了对比,

首先创建一个WebSite项目(必须是WebSite,否则无法正常生成数据和使用内置函数!),然后创建以下3个页面:Default.aspx(一个Login控件),Register.aspx(一个CreateUserWizard控件)和一个ForgetPassword.aspx(一个密码遗忘控件:PasswordRecovery)。把Default设置成默认起始页,然后添加以下代码到web.config:

<location path="Default2.aspx">

<system.web>

<authorization>

<allow users="*"/>

</authorization>

</system.web>

</location>

<location path="ForgetPassword.aspx">

<system.web>

<authorization>

<allow users="*"/>

</authorization>

</system.web>

</location>

<system.web>

<compilation debug="true" targetFramework="4.0"/>

<authentication mode="Forms">

<forms path="/" timeout="60" slidingExpiration="true" loginUrl="Default.aspx"/>

</authentication>

<authorization>

<allow users="*"/>

<deny users="?"/>

</authorization>

同时,将您的Login控件转成一个Template的模式(允许自定义样式,比如添加一些其它控件等),添加一个“Register”和“Forget Password”LinkButton,指定其PostBackUrl,以便使其点击成功跳转到注册和密码遗忘的页面:

<asp:Login runat="server"

onauthenticate="Login1_Authenticate">

<LayoutTemplate>

<table cellpadding="1" cellspacing="0" >

<tr>

<td>

<table cellpadding="0">

<tr>

<td align="center" colspan="2">

Log In</td>

</tr>

<tr>

<td align="right">

<asp:Label runat="server" AssociatedControl>User Name:</asp:Label>

</td>

<td>

<asp:TextBox runat="server"></asp:TextBox>

<asp:RequiredFieldValidator runat="server"

ControlToValidate="UserName" ErrorMessage="User Name is required."

ToolTip="User Name is required." ValidationGroup="Login1">*</asp:RequiredFieldValidator>

</td>

</tr>

<tr>

<td align="right">

<asp:Label runat="server" AssociatedControl>Password:</asp:Label>

</td>

<td>

<asp:TextBox runat="server" TextMode="Password"></asp:TextBox>

<asp:RequiredFieldValidator runat="server"

ControlToValidate="Password" ErrorMessage="Password is required."

ToolTip="Password is required." ValidationGroup="Login1">*</asp:RequiredFieldValidator>

</td>

</tr>

<tr>

<td colspan="2">

<asp:CheckBox runat="server" Text="Remember me next time." />

</td>

</tr>

<tr>

<td align="center" colspan="2" >

<asp:Literal runat="server" EnableViewState="False"></asp:Literal>

</td>

</tr>

<tr>

<td align="left">

<asp:Button runat="server" CommandName="Login" Text="Log In"

ValidationGroup="Login1" />

</td>

<td align="right">

<asp:LinkButton runat="server" PostBackUrl="~/Register.aspx">Register Now</asp:LinkButton>

&nbsp;&nbsp;

<asp:LinkButton runat="server"

PostBackUrl="~/ForgetPassword.aspx">Forget Password</asp:LinkButton>

</td>

</tr>

</table>

</td>

</tr>

</table>

</LayoutTemplate>

</asp:Login>

在Register中放上一个CreateUserWizard控件。在ForgetPassword页面放上一个PasswordRecovery控件。同时在web.config中添加以下配置(位于<system.web>节点外):

<system.net>

<mailSettings>

<smtp from="发送方地址xxx@abc.com" deliveryMethod="Network">

<network host="smtp服务器地址(smtp.xx.xx)" userName="登录用户名" password="口令" defaultCredentials="服务器要求验证" />

</smtp>

</mailSettings>

</system.net>

同时对于PasswordRecovery控件中作如下定义:

<asp:PasswordRecovery runat="server" >

<MailDefinition Subject="邮件主题" />

</asp:PasswordRecovery>

基本上这样,一个非常简单的注册功能的多页面“项目”就完成了。简单吧。下面我们分析它的原理:

1、首先看Default.aspx页面部分:如果是WebSite工程,当放入一个Login的控件的时候,它会在根目录的一个叫“APP_DATA”的特别文件夹里(如果看不到请右键项目,选择添加ASP.NET文件夹,选择即可)创建一个ASPNETDB.MDF数据库文件。并且创建了相关的表以便后续的用户注册等操作。

2、在Register.aspx页面中存在一个CreateuserWizard控件,该控件一旦当用户输入用户名等注册信息之后,自动触发CreatingUser事件,同时调用Membership.CreateUser内置类把信息逐一写入那个自动生成的数据库中,其函数声明如下:

public static MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, out MembershipCreateStatus status);

其它的参数可以通过英文名字就逐一得知,我就不罗嗦了;这里需要注意两个特别的参数:“isApproved”是表示是否将该用户停用;“MembershipCreateStatus”是一个枚举,用于报告创建的情况(如果成功,将会是Success)。您完全可以在“CreateUserWizard1_CreateUserError”事件中通过“e.CreateUserError”来获取失败的信息,做特殊处理。

3、在ForgetPassword.aspx页面中,首先你输入一个用户名,系统在VerfyingUser事件中调用Membership.GetUser(string username)获得一个MembershipUser的实例。如果不存在,则表示错误,自动让e.Cancel = true(取消下一步操作)。如果成功,则e.Cancel=false进入下一步,同时获取MemberShipUser的Answer(没有直接提供属性访问)和你输入的进行比较,对则发送email(自动读取<system.net>的节点中的内容,对应如下代码):

SmtpClient s = new SmtpClient();

MailMessage ms = new MailMessage();

ms.From = new MailAddress("发送方");

ms.To.Add(new MailAddress("接收方"));

ms.Subject = "邮件主题";

ms.Body = "邮件正文";

s.DeliveryMethod = SmtpDeliveryMethod.Network; //发送方式

s.Host ="smtp.xxx.xxx";

s.Credentials = new NetworkCredential("发送方邮箱用户名", "口令");

s.Send(ms);