说到用户登录,大家都不陌生了。用户登录很简单,但是他却又不那么简单,往往可以通过对用户登录的设计就可以看出一个程序员的开发水平了。那怎样的用户登录还算不错呢?Forms身份认证+记住密码+加密存储+LoginedPage/BasePage,虽然比不上大牛神一样的代码,但包括这些东西在里面能应付大多数程序了,我们来一一看看。
1.Forms身份认证。Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活。Forms 验证方式对基于用户的验证授权提供了很好的支持,可以通过一个登录页面验证用户的身份,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个web应用就会连同这个身份Cookie一起发送到服务端。服务端上的授权设置就可以根据不同目录对不同用户的访问授权进行控制了。具体还不清楚的看这里点击打开链接 经典FormsAuthenticationTicket 分析 。
2.记住密码。这个不多说,大家都知道。
3.加密存储。这个作为程序员大家也知道,为了加强安全性。
4.LoginedPage/BasePage。有的人喜欢叫LoginedPage,有的人喜欢叫BasePage,实际上都差不多。很多时候,我们只使用他用来验证权限,其实他还可以用来获取存储用户信息,这样你在用到用户信息的时候就不用再去查询一遍数据库了。
以上是简单介绍,下面详细看一下。
一、Forms身份认证+记住密码+加密存储
用户登录信息验证通过之后(具体验证步骤就不写了),我们查询出用户信息(员工实体)。首先,判断是否记住密码来选择Cookie过期时间,然后建立Forms身份验证票,最后将常用的用户信息存储到Cookie中(以备下一步使用),注意,储存Cookie都是加密滴,密码存储到数据也是MD5加密的,但是存到Cookie中再加一次。
/// <summary>
/// 存储员工信息到Cookie
/// </summary>
/// <param name="mode"></param>
/// <param name="expires"></param>
private void SaveEmloyeeInfo(emp_EmployeeModel mode)
{
try
{
DateTime expires = new DateTime();
if (cb_Remember.Checked == true)
{//记住密码
expires = DateTime.Now.AddDays(30);
}
else
{
expires = DateTime.Now.AddMinutes(30);
}
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(1, mode.EmpNumber, DateTime.Now, expires, true, mode.ID.ToString(), "/"); //建立身份验证票对象
string HashTicket = FormsAuthentication.Encrypt(Ticket); //加密序列化验证票为字符串
HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket);
//生成Cookie
Response.Cookies.Add(UserCookie);
//存储员工信息到Cookie
CookieHelper.SetCookie("Id", DEncrypt.Encrypt(mode.ID.ToString()), expires);
CookieHelper.SetCookie("EmpNumber", DEncrypt.Encrypt(mode.EmpNumber), expires);
CookieHelper.SetCookie("EmpName", DEncrypt.Encrypt(mode.EmpName), expires);
CookieHelper.SetCookie("EmpDepartmentName", DEncrypt.Encrypt(mode.EmpDepartmentName), expires);
CookieHelper.SetCookie("EmpPositionName", DEncrypt.Encrypt(mode.EmpPositionName), expires);
CookieHelper.SetCookie("LoginPwd", DEncrypt.Encrypt(mode.LoginPwd), expires);
Response.Redirect("index.html");
}
catch (Exception)
{
}
}
二、LoginedPage/BasePage
这个页面有两个作用,一是验证用户权限和登陆状态(我这里只写了验证登陆状态,用户权限同理);二是获取常用的用户信息,而不必每次都去查表。分别说一说原理:
1.如代码所示,我们的LoginedPage页面首先要继承System.Web.UI.Page类,为什么呢?因为我们要验证的页面是要继承LoginedPage页面的,比如首页啊、列表页,而这些web层的页面必须继承System.Web.UI.Page才能有加载事件、使用各种控件等等。 然后我们重写Page_Load方法,在这里做页面加载时的判断,即验证用户登录状态和权限。如此一来,只要需要验证的页面继承LoginedPage类就行了
2.看代码下面,我们定义了常用用户字段信息,并且它的值获取的正是上一步中存储到Cookie中的信息,并且解密。那我们在用到用户信息的时候直接使用该属性字段就行啦,是不是很方便?
using Maticsoft.Common;
using Maticsoft.Common.DEncrypt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
namespace trip.Common
{
public class LoginedPage: System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.Load += new System.EventHandler(LoginedPage_Load);
}
/// <summary>
/// 判断用户状态、权限
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LoginedPage_Load(object sender, EventArgs e)
{
if (!User.Identity.IsAuthenticated)
{
MessageBox.ShowAndRedirectParent(this.Page, "禁止非法登录!",1, "Login.aspx");
}
}
/// <summary>
/// 员工ID
/// </summary>
public static Int32 Id
{
get { return string.IsNullOrEmpty(CookieHelper.GetCookieValue("Id")) ? 0 : Convert.ToInt32(DEncrypt.Decrypt(CookieHelper.GetCookieValue("Id"))); }
}
/// <summary>
/// 员工编号
/// </summary>
public static String EmpNumber
{
get { return string.IsNullOrEmpty(CookieHelper.GetCookieValue("EmpNumber")) ? "" : DEncrypt.Decrypt(CookieHelper.GetCookieValue("EmpNumber")); }
}
/// <summary>
/// 员工姓名
/// </summary>
public static String EmpName
{
get { return string.IsNullOrEmpty(CookieHelper.GetCookieValue("EmpName")) ? "" : DEncrypt.Decrypt(CookieHelper.GetCookieValue("EmpName")); }
}
/// <summary>
/// 部门名称
/// </summary>
public static String EmpDepartmentName
{
get { return string.IsNullOrEmpty(CookieHelper.GetCookieValue("EmpDepartmentName")) ? "" : DEncrypt.Decrypt(CookieHelper.GetCookieValue("EmpDepartmentName")); }
}
/// <summary>
/// 岗位名称
/// </summary>
public static String EmpPositionName
{
get { return string.IsNullOrEmpty(CookieHelper.GetCookieValue("EmpPositionName")) ? "" : DEncrypt.Decrypt(CookieHelper.GetCookieValue("EmpPositionName")); }
}
/// <summary>
/// 登陆密码
/// </summary>
public static String LoginPwd
{
get { return string.IsNullOrEmpty(CookieHelper.GetCookieValue("LoginPwd")) ? "" : DEncrypt.Decrypt(CookieHelper.GetCookieValue("LoginPwd")); }
}
}
}
三、验证密码通过自动登录
这步就不多说了,就是验证下Cookie中用户名和密码是否存在且正确,正确的话自动建立身份验证票,跳转到首页。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
emp_EmployeeModel mode = emp_EmployeeBLL.Instance.Login(LoginedPage.EmpNumber, LoginedPage.LoginPwd);
if (mode == null)
{
MessageBox.Show(this.Page, "您的用户信息已失效!", 5);
return;
}
SaveEmloyeeInfo(mode);
if (User.Identity.IsAuthenticated)
{
Response.Redirect("index.html");
}
}
}