zoukankan      html  css  js  c++  java
  • Asp.net mvc验证用户登录之Forms实现

    这里我们采用asp.net mvc 自带的AuthorizeAttribute过滤器验证用户的身份,也可以使用自定义过滤器,步骤都是一样。

    第一步:创建asp.net mvc项目, 在项目的App_Start文件夹下面有一个FilterConfig.cs,在这个文件中可以注册全局的过滤器。我们在文件中添加AuthorizeAttribute过滤器如下:

       public class FilterConfig
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
                //将内置的权限过滤器添加到全局过滤中
                filters.Add(new System.Web.Mvc.AuthorizeAttribute());
            }
        }

    第二步:在web.config配置文件中修改网站的身份认证为mode="Forms"

      <system.web>
        <!--Cockie名称,当用未登入时跳转的url-->
        <authentication mode="Forms">
          <forms name="xCookie" loginUrl="~/Login/Index" protection="All" timeout="60" cookieless="UseCookies"></forms>
        </authentication>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
      </system.web>

    提示:配置name值作为最终生成的cookie的名称,loginUrl指定当用户未登入是跳转的页面,这里挑战到登入页面

    第三步:添加用户登入相关的控制器和视图

    创建LoginController控制器:

       public class LoginController : Controller
        {
            [HttpGet]
            [AllowAnonymous]
            public ActionResult Index()
            {
                return View();
            }
    
            [HttpPost]
            [AllowAnonymous]
            public ActionResult Login(User user) 
            {
                if (!user.Username.Trim().Equals("liuxin") || !user.Password.Trim().Equals("abc"))
                {
                    ModelState.AddModelError("", "用户名或密码错误");
                    return View("index", user);
                }
                //if (!user.Username.Trim().Equals("liuxin")) {
                //    ModelState.AddModelError("Username", "用户名错误");
                //    return View("index", user);
                //}
                //if (!user.Password.Trim().Equals("abc")) {
                //    ModelState.AddModelError("Password", "密码错误");
                //    return View("index", user);
                //}
                user.Id = Guid.NewGuid().ToString("D");//为了测试手动设置一个用户id
                FormsAuthHelp.AddFormsAuthCookie(user.Id, user, 60);//设置ticket票据的名称为用户的id,设置有效时间为60分钟
                return Redirect("~");
            }
            [HttpGet]
            public ActionResult Logout() {
                FormsAuthHelp.RemoveFormsAuthCookie();
                return Redirect("~/Login/Index");
            }
        }

    特别注意:Index和Login这两个方法得使用“[AllowAnonymous]”指明这两个方法可以匿名访问,否则由于过滤器不允许匿名访问,导致登入页面和用户提交都无法进行。显然这不是我们希望看到的。

    提示:为了测试方便这边的用户的数据是写死的,用户的id也是临时生成了一个

       public class User
        {
            public string Id { get; set; }
            public string Username { get; set; }
            public string Password { get; set; }
        }

    创建登入视图:

    @{
        Layout = null;
        ViewBag.Title = "Index";
    }
    <h3>您尚未登入,请登入</h3>
    @using(Html.BeginForm("Login", "Login", FormMethod.Post))
    {
        @Html.Label("Username", "用户名:")@Html.TextBox("Username", null, new { id = "Username", placeholder = "请输入用户名" })
        @Html.ValidationMessage("Username")<br/>
        @Html.Label("Password", "密  码:")@Html.TextBox("Password", null, new { id = "Password", placeholder = "请输入密码" })
        @Html.ValidationMessage("Password")<br/>
        <input type="submit" value="登入" />  <input type="reset" value="重置" />
        @Html.ValidationSummary(true)
    }

    提示:当检测到用户未登入,则跳转到web.config中配置的url页面,当用户填写密码并提交时,用户输入的数据会提交到LoginController控制器下的Login方法,验证用户的输入,认证失败重新返回到登入界面,当认证成功,将会执行

    <<***FormsAuthHelp.AddFormsAuthCookie(user.Id, user, 60);//设置ticket票据的名称为用户的id,设置有效时间为60分钟***>>,这条语句的作用是生成一个ticket票据,并封装到cookie中,asp.net mvc正式通过检测这个cookie认证用户是否登入的,具体代码如下

    第四步:将用户信息生成ticket封装到cookie中

       public class FormsAuthHelp
        {
            /// <summary>
            /// 将当前登入用户的信息生成ticket添加到到cookie中(用于登入)
            /// </summary>
            /// <param name="loginName">Forms身份验证票相关联的用户名(一般是当前用户的id,作为ticket的名称使用)</param>
            /// <param name="userData">用户信息</param>
            /// <param name="expireMin">有效期</param>
            public static void AddFormsAuthCookie(string loginName, object userData, int expireMin)
            {
                //将当前登入的用户信息序列化
                var data = JsonConvert.SerializeObject(userData);
    
                //创建一个FormsAuthenticationTicket,它包含登录名以及额外的用户数据。
                var ticket = new FormsAuthenticationTicket(1,
                    loginName, DateTime.Now, DateTime.Now.AddDays(1), true, data);
    
                //加密Ticket,变成一个加密的字符串。
                var cookieValue = FormsAuthentication.Encrypt(ticket);
    
                //根据加密结果创建登录Cookie
                //FormsAuthentication.FormsCookieName是配置文件中指定的cookie名称,默认是".ASPXAUTH"
                var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue)
                {
                    HttpOnly = true,
                    Secure = FormsAuthentication.RequireSSL,
                    Domain = FormsAuthentication.CookieDomain,
                    Path = FormsAuthentication.FormsCookiePath
                };
                //设置有效时间
                if (expireMin > 0)
                    cookie.Expires = DateTime.Now.AddMinutes(expireMin);
    
                var context = HttpContext.Current;
                if (context == null)
                    throw new InvalidOperationException();
    
                //写登录Cookie
                context.Response.Cookies.Remove(cookie.Name);
                context.Response.Cookies.Add(cookie);
            }
            /// <summary>
            /// 删除用户ticket票据
            /// </summary>
            public static void RemoveFormsAuthCookie() {
                FormsAuthentication.SignOut();
            }
        }

    第五步:测试执行

    1. 启动网站输入相应的网址:如下图

      

    2. 此时用户尚未登入将会跳转到登入界面:如下图

      

    3. 输入错误的密码会重新跳转到登入界面并提示出错

      

    4. 输入正确的用户名密码

      

    5. 点击用户退出会删除掉cookie所以又会跳转到登入界面

     测试源码下载地址:链接: https://pan.baidu.com/s/1cm722q 密码: ut53

  • 相关阅读:
    iOS重签名及问题总结
    安装class-dump
    UISearchController 很坑
    hashmap 之哈希冲突
    wait()与sleep()的区别
    docker之es+es-head+kibana+ik分词器安装
    MySQL很有用的命令
    分布式事务执行逻辑
    索引 创建原则
    合理使用存储引擎
  • 原文地址:https://www.cnblogs.com/enfp/p/7723973.html
Copyright © 2011-2022 走看看