private void Btn_Login_Click(object sender, System.EventArgs e) { if(this.Txt_UserName.Text=="Admin" && this.Txt_Password.Text=="123456") { FormsAuthentication.RedirectFromLoginPage(this.Txt_UserName.Text,false); } }
此处只是简单模拟了一下登录的验证过程,RedirectFromLoginPage方法能发送验证票据验证Cookie(如何进行可以用Reflector去查看源代码),返回请求页面,即“从哪来就打哪去”。比如:用户没登录前直接在 IE 地址栏输入 ,那么该用户将看到的是 Login.aspx?ReturnUrl=Default.aspx ,输入用户名与密码登录成功后,系统将根据“ReturnUrl”的值,返回相应的页面;如果没有“ReturnUrl”,则按照“defaultUrl”的属性自动转向。
方法二:
private void Btn_Login_Click(object sender, System.EventArgs e) { if(this.Txt_UserName.Text=="Admin" && this.Txt_Password.Text=="123456") { FormsAuthentication.SetAuthCookie(this.Txt_UserName.Text,false); Response.Redirect("Default.aspx"); } }
此处是分两步走:通过验证后就直接发放 Cookie ,跳转页面将由程序员自行指定,无需“defaultUrl”设置。此方法对于程序员来说,更灵活。
2、手工实现需要记录用户登录信息的情况
当我们需要记录用户登录的信息,不单单只是一个ID还需要更多属性的时候,一般都用一个类存储到Session或Cookie实现,然后做一个基类页,在基类页中设置属性来读取Session或Cookie。
Session实际也和支不支持Cookie有关,且存在服务器,多少会占用服务器端资源。因此这里还是考虑用Cookie实现。那么在RedirectFromLoginPage方法或SetAuthCookie方法已经设置了验证票据并设置了Cookie,我们能不能把用户登录信息也存储到这个默认的Cookie里呢?答案是能。
首先,我们在项目里添加AppCode目录,增加一个UserInfo的类,用以简单模拟用户登录信息。代码如下:
[Serializable] public class UserInfo { //用户登录信息 private int _nId; private string _sRealName; private string _sName; private string _sPassword; private string _sRoles; public int Id { get { return this._nId; } set { this._nId = value; } } public string RealName { get { return this._sRealName; } set { this._sRealName = value; } } public string Name { get { return this._sName; } set { this._sName = value; } } public string Password { get { return this._sPassword; } set { this._sPassword = value; } } public string Roles { get { return this._sRoles; } set { this._sRoles = value; } } public UserInfo() { } }
需要注意, 类的属性中一定要加[Serializable],表示类可以序列化。
Forms验证在内部的机制是,把用户数据加密后保存在一个基于cookie的票据FormsAuthenticationTicket中,通过RedirectFromLoginPage方法或SetAuthCookie方法就已经实现了Ticket和Cookie的设置,也就是设置了Context.User的值,Context.User在取值和判断是否经过验证的时候很有用处。Cookie的属性是在Web.config的<forms name=".ASPXAUTH" loginUrl="Login.aspx" protection="All" path="https://www.jb51.net/" timeout="20"/>中设置的。因为是经过特殊加密的,所以应该来说是比较安全的。
而.net除了用这个票据存放自己的信息外,还留了一个地给用户自由支配,这就是现在要说的Ticket的UserData。 UserData用来存储string类型的信息,并且也享受Forms验证提供的加密保护,当我们需要这些信息时,也可以通过简单的Ticket的 UserData属性得到,兼顾了安全性和易用性,用来保存一些必须的敏感信息还是很有用的。我们就准备将用户的登录信息记录在UserData中,代码如下:
protected void Button1_Click(object sender, EventArgs e) { if (this.TextBox1.Text == "Admin" && this.TextBox2.Text == "123456") { // 加密UserInfo UserInfo user = new UserInfo(); user.Id = 1; user.Name = this.TextBox1.Text; user.Password = this.TextBox2.Text; user.RealName = "系统管理员"; user.Roles = "Administrators,Users"; string strUser = Serialize.Encrypt<UserInfo>(user); // 设置Ticket信息 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket( 1, user.Name, DateTime.Now, DateTime.Now.AddMinutes(20), false, strUser); // 加密验证票据 string strTicket = FormsAuthentication.Encrypt(ticket); // 使用新userdata保存cookie HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strTicket); cookie.Expires = ticket.Expiration; this.Response.Cookies.Add(cookie); this.Response.Redirect("Default.aspx"); } }
上面的代码,实际上类似于手工实现了SetAuthCookie方法的过程。