MVC过滤器进行统一登录验证
统一登录验证:
1、定义实体类Person:利用特性标签验证输入合法性设计登录页面
1
2
3
4
5
6
7
8
9
|
public class Person { [DisplayName( "用户名" ), Required(ErrorMessage = "账户非空!" )] public string LoginName { get ; set ; } [DisplayName( "密 码" ), Required(ErrorMessage = "密码非空!" )] public string Password { get ; set ; } [DisplayName( "验证码" ), Required(ErrorMessage = "验证码非空!" )] public string Vcode { get ; set ; } } |
2、设计验证码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
public class VcodeController : Controller { // // GET: /Vcode/ public ActionResult Vcode() { byte [] buffer; string str = GetRdStr(5); //将生成随机字符串存入session中 Session[ "vcode" ] = str; using (Image img= new Bitmap(80,30)) { using (Graphics g=Graphics.FromImage(img)) { //清除背景色 g.Clear(Color.White); g.DrawRectangle(Pens.Black, 0, 0, img.Width - 1, img.Height - 1); DrawLines(50, img, g); g.DrawString(str, new Font( "微软雅黑" , 16), Brushes.Black, 0, 0); DrawLines(35, img, g); } using (System.IO.MemoryStream ms= new System.IO.MemoryStream()) { img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); buffer=ms.ToArray(); } } return File(buffer, "image/jpeg" ); } /// <summary> /// 定义随机对象 /// </summary> Random rd = new Random(); /// <summary> /// 生产指定长度随机字符串 /// </summary> /// <returns>随机字符串</returns> string GetRdStr( int count) { string str = "abcdefghijkmnpqrstuvwxyzABCDEFGHIJKMNPQRSTUVWXYZ23456789" ; System.Text.StringBuilder sb = new System.Text.StringBuilder(); for ( int i=0;i<count;i++) { sb.Append(str[rd.Next(str.Length)]); } return sb.ToString(); } /// <summary> /// 绘制指定数量干扰线 /// </summary> /// <param name="count">数量</param> /// <param name="img">图片对象</param> /// <param name="g">画家对象</param> void DrawLines( int count,Image img,Graphics g) { for ( int i=0;i<count;i++) { Point p1 = new Point(rd.Next(img.Width - 1), rd.Next(img.Height - 1)); Point p2 = new Point(p1.X + rd.Next(-1, 2), p1.X + rd.Next(-1, 2)); g.DrawLine(Pens.AliceBlue, p1, p2); } } } |
3、设计登录页面,并写入登录逻辑
前台页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
@{ ViewBag.Title = "Login"; } @using 统一登录2.Models @model Person < script src = "~/Scripts/jquery.validate.js" ></ script > < script src = "~/Scripts/jquery.validate.unobtrusive.js" ></ script > @using (@Html.BeginForm("Login", "Login", FormMethod.Post)) { < table > < tr > < th >@Html.DisplayNameFor(p => p.LoginName)</ th > < td > @Html.TextBoxFor(p => p.LoginName) @Html.ValidationMessageFor(p => p.LoginName) </ td > </ tr > < tr > < th >@Html.DisplayNameFor(p => p.Password)</ th > < td > @Html.PasswordFor(p => p.Password) @Html.ValidationMessageFor(p => p.Password) </ td > </ tr > < tr > < th >@Html.DisplayNameFor(p => p.Vcode)</ th > < td > @Html.TextBoxFor(p => p.Vcode) < img src = "@Url.Action(" Vcode", "Vcode")" /> @Html.ValidationMessageFor(p => p.Vcode) </ td > </ tr > < tr > < th ></ th > < td > < input type = "submit" value = "登录" /> </ td > </ tr > </ table > } < script type = "text/javascript" > </ script > |
后台逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
public class LoginController : Controller { // // GET: /Login/ [HttpGet] public ActionResult Login() { return View(); } [HttpPost] public ActionResult Login(Person model) { //判断实体验证是否成功 if (ModelState.IsValid == false ) { ModelState.AddModelError( "" , "实体验证失败!" ); return View(); } //判断验证码验证是否成功 if (Session[ "vcode" ]!= null &&Session[ "vcode" ].ToString().Equals(model.Vcode,StringComparison.OrdinalIgnoreCase)) { ModelState.AddModelError( "" , "验证码输入不正确!" ); return View(); } //判断账户密码验证是否成功 if (model.LoginName!= "admin" ||model.Password!= "123" ) { ModelState.AddModelError( "" , "用户名或密码错误!" ); return View(); } //登录成功,登录信息存入Session Session[ "uInfo" ] = model; //跳转到主页面 return RedirectToAction( "Index" , "Home" ); } } |
4、在过滤器中写入统一验证逻辑--注:这里用标签来判断是否需要进行登录验证,标签类实在第五步定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public override void OnActionExecuting(ActionExecutingContext filterContext) { //判断是否需要登录验证 if (filterContext.ActionDescriptor.IsDefined( typeof (IgnoreLoginAttribute), false )) { return ; } if (filterContext.ActionDescriptor.ControllerDescriptor.IsDefined( typeof (IgnoreLoginAttribute), false )) { return ; } //根据Session进行登录验证 if (filterContext.HttpContext.Session[ "uInfo" ]== null ) { //1.Ajax请求 if (filterContext.HttpContext.Request.IsAjaxRequest()) { JsonResult jsonView = new JsonResult(); jsonView.ContentType = "application/json" ; jsonView.Data = new {status=2,msg= "未登录" }; jsonView.JsonRequestBehavior = JsonRequestBehavior.AllowGet; filterContext.Result = jsonView; } //2.一般请求 else { ContentResult contentView = new ContentResult(); contentView.Content = "<script>window.alert('您还没有登录!请重新登录...');window.location='/Login/Login'</script>" ; filterContext.Result = contentView; } } } |
5、定义自定义特性标签,不需要登录验证统一贴上特性标签
1
2
3
4
5
6
7
|
/// <summary> /// 是否忽略登录验证特性标签 /// </summary> [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple= false )] public class IgnoreLoginAttribute:Attribute { } |