ASP.NET MVC登录实现Cookie加密以及过滤器简单使用

  1. 封装BaseService类,里面是写好的增删改查的各种方法
 public class BaseService<T> where T:class,new ()
    {
        /// <summary>
        /// 实例化数据访问上下文
        /// </summary>
        //private MemberPointEntity mpe = new MemberPointEntity();
       
        protected readonly DbContext mpe = ContextFactory.GetCurrentContext();
        /// <summary>
        /// 实现添加信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool Add(T model)
        {
            mpe.Entry(model).State = EntityState.Added;
            return mpe.SaveChanges() > 0;
        }
        /// <summary>
        /// 实现删除信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool Remove(T model)
        {
            mpe.Set<T>().Attach(model);
            mpe.Entry<T>(model).State = EntityState.Deleted;
            return mpe.SaveChanges() > 0;
        }
        /// <summary>
        /// 实现修改信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool Edit(T model)
        {
            mpe.Set<T>().Attach(model);
            mpe.Entry(model).State = EntityState.Modified;
            return mpe.SaveChanges() > 0;
        }
        /// <summary>
        /// 查询一行
        /// </summary>
        /// <param name="lamwhere"></param>
        /// <returns></returns>
        public T Find(Expression<Func<T, bool>> lamwhere)
        {
            return mpe.Set<T>().Where(lamwhere).FirstOrDefault();
        }
        /// <summary>
        /// 查询表
        /// </summary>
        /// <param name="lamwhere"></param>
        /// <returns></returns>
        public IQueryable<T> GetList(Expression<Func<T, bool>> lamwhere)
        {
            return mpe.Set<T>().Where(lamwhere);
        }
        /// <summary>
        /// 查询表,排序
        /// </summary>
        /// <param name="lamwhere"></param>
        /// <returns></returns>
        public IQueryable<T> GetList<TKey>(Expression<Func<T, bool>> lamwhere,Expression<Func<T,TKey>> orderby,bool isAsc=true)
        {
            if (isAsc)
            {
                return mpe.Set<T>().Where(lamwhere).OrderBy(orderby);
            }
            else
            {
                return mpe.Set<T>().Where(lamwhere).OrderByDescending(orderby);
            }
        }
        /// <summary>
        /// 查询表,排序,分页
        /// </summary>
        /// <param name="lamwhere"></param>
        /// <returns></returns>
        public IQueryable<T> GetList<TKey>(int pageIndex,int pageSize,ref int TotalCount,Expression<Func<T, bool>> lamwhere, Expression<Func<T, TKey>> orderby, bool isAsc = true)
        {
            TotalCount = mpe.Set<T>().Count(lamwhere);
            pageIndex = pageIndex - 1 < 1 ? 1 : pageIndex;
            if (isAsc)
            {
                return mpe.Set<T>().Where(lamwhere).OrderBy(orderby).Skip((pageIndex-1)*pageSize).Take(pageSize);
            }
            else
            {
                return mpe.Set<T>().Where(lamwhere).OrderByDescending(orderby).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
        }
  1. 编写B层(业务逻辑层)Login方法
    首先在公共层封装一个序列化和反序列化的方法
	/// <summary>
        /// 对象转json,序列化
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJson(this object obj)
        {
            return JsonConvert.SerializeObject(obj);
        }
        /// <summary>
        /// json转对象,反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="str"></param>
        /// <returns></returns>
        public static T ToObject<T>(this string str)
        {
            if (!string.IsNullOrWhiteSpace(str))
            {
                return JsonConvert.DeserializeObject<T>(str);
            }
            else
            {
                return default(T);
            }
        }

然后封装一个加密写入Cookie的方法

	 /// <summary>
        /// 将用户信息对象转换为Json格式,创建票据并进行加密,最后放入Cookie
        /// </summary>
        /// <param name="dtomodel"></param>
        public void UserInfoToCookid(LoginUserDTOModel dtomodel)
        {
            //var data = JsonOrObject.ToJson(dtomodel);
            var data = dtomodel.ToJson();//获取用户数据转换为Json
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, "loginUser",DateTime.Now,DateTime.Now.AddDays(1),false,data);//创建票据FormsAuthenticationTicket
            var EncryptionTicket = FormsAuthentication.Encrypt(ticket);//对票据进行加密
            //创建Cookie HttpCookie FormsAuthentication.FormsCookieName
            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, EncryptionTicket);//读取配置文件Forms 的name值 
            cookie.HttpOnly = true;
            cookie.Secure= FormsAuthentication.RequireSSL;
            cookie.Domain = FormsAuthentication.CookieDomain;
            cookie.Path = FormsAuthentication.FormsCookiePath;
            cookie.Expires = DateTime.Now.Add(FormsAuthentication.Timeout);

            HttpContext context = HttpContext.Current;
            if (context==null)
            {
                throw new ArgumentNullException("context为空");
            }
            //写入Cookie     先删除再添加
            context.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
            context.Response.Cookies.Add(cookie);
        }

配置文件里面配置以下内容
<authentication mode="Forms"> <forms name="LoginName" loginUrl="/Admin/Login" cookieless="UseCookies" path="/" protection="All" timeout="30"></forms> </authentication>

封装OperaterResult类用于接收结果以及数据

 public class OperaterResult
    {
        public ResultStatus Status { get; set; }       //该处用枚举类型,不管任何处理无非两种结果,成功和失败
        public string Msg { get; set; }
        public object Date { get; set; }
        public OperaterResult(ResultStatus status,string msg)
        {
            this.Status = status;
            this.Msg = msg;
        }
        public OperaterResult(ResultStatus status, string msg,object date)
        {
            this.Status = status;
            this.Msg = msg;
            this.Date = date;
        }
    }
    /// <summary>
    /// 枚举,放两种结果
    /// </summary>
    public enum ResultStatus
    {
        Success=1,
        Error=-1
    }

最后写登录方法

	public OperaterResult Login(LoginViewModel model)
        {
            model.PassWord = EncodeHelper.GetMD5Hash(model.PassWord);
            var GetModel = Find(u => u.U_LoginName == model.UserName && u.U_Password == model.PassWord);
            if (GetModel == null)
            {
                return new OperaterResult(ResultStatus.Error, "用户名或密码不匹配!");
            }
            else
            {
                var datamodel = new LoginUserDTOModel()
                {
                    Id = GetModel.U_ID,
                    UserName = GetModel.U_LoginName,
                    RealName = GetModel.U_RealName
                };
                //存入cookie并加密
                UserInfoToCookid(datamodel);
                return new OperaterResult(ResultStatus.Success, "登录成功!");
            }
        }
  1. 创建好控制器,和Login视图 调用B层登录方法
	UsersService user = new UsersService();   //实力化对象,调用方法
	public ActionResult Login()
        {
            return View();
        }
        [HttpPost]
        public ActionResult Login(LoginViewModel model)
        {
            //模型校验
            if (ModelState.IsValid)
            {
                var Result = user.Login(model);
                if (Result.Status == ResultStatus.Success)
                {
                    var returnUrl = Request["ReturnUrl"];
                    if (!string.IsNullOrWhiteSpace(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    return Redirect("~/Index.html");
                }
                else
                {
                    ModelState.AddModelError("", Result.Msg);
                }
            }
            else
            {
                ModelState.AddModelError("", "输入的用户名或密码有误!");
            }
            return View();
        }
  • 给每个页面添加校验,过滤器的使用

首先写个方法,用于实例化上下文中的User数据

 public class MyFormsPrincipal<T> : IPrincipal where T : class, new()
    {
        //   1. 定义MyFormsPrincipal<T> 实现IPrincipal接口
        //   2. 定义两个属性和字段 IIdentity _identity,T _userData,并且构造Get访问器

        //   3. 创建一个构造函数MyFormsPrincipal(FormsAuthenticationTicket ticket, T userData)

        //    对_identity进行实例化 new FormsIdentity(ticket);
        //        userData进行赋值
        //    实现IsInRole方法 public bool IsInRole(string role)

        //    将_userData 转为IPrincipal接口

        //    调用IsInRole方法
        

        public IIdentity Identity
        {
            get;
            private set;
        }

        public T UserData { get; private set; }

        public MyFormsPrincipal(FormsAuthenticationTicket ticket, T userData)
        {
            this.Identity = new FormsIdentity(ticket);
            this.UserData = userData;
        }

        public bool IsInRole(string role)
        {
            IPrincipal principal = UserData as IPrincipal;
            if (principal == null)
                throw new ArgumentNullException("principal");
            return principal.IsInRole(role);
        }
    }

然后编写Global.asax

//引入命名空间
	using System.Web.Optimization;
	using System.Web.Routing;
	using System.Web.Security;

	protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            //  1.通过sender获取HttpApplication

            HttpApplication app = sender as HttpApplication;
            //2.拿到HTTP上下文
            HttpContext context = app.Context;
            //3.根据FormsAuthentication.FormsCookieName从上下文请求中获取到Cookie
            var cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (cookie != null)
            {
                //4.解密cookie.Value获得票据
                if (!string.IsNullOrWhiteSpace(cookie.Value))
                {
                    var ticket = FormsAuthentication.Decrypt(cookie.Value);
                    //5.判断票据的UserData,如果不为空则反序列化为实体
                    if (!string.IsNullOrWhiteSpace(ticket.UserData))
                    {
                        var dtoModel = ticket.UserData.ToObject<LoginUserDTOModel>();

                        //6.将上下文中的User数据实例化,通过MyFormsPrincipal的构造函数 ticket,userData
                        context.User = new MyFormsPrincipal<LoginUserDTOModel>(ticket, dtoModel);
                    }
                }
            }
        }

然后在控制器里面加过滤器,使用方法

	 [Authorize]   //加这行就可以,过滤器

猜你喜欢

转载自blog.csdn.net/qq_42898553/article/details/82855072