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{} |
浙公网安备 33010602011771号