zoukankan      html  css  js  c++  java
  • ASP.NET MVC 实现页落网资源分享网站+充值管理+后台管理(9)之系统登录

        前面我们已经做好了一个文章管理功能模块,接下来,我们回头来做登录窗口,登录不仅涉及到登录验证还涉及到登录日志还有缓存时长等。

        对于缓存的相关设置,我们已经写好封装在Bobo.Utilities.dll程序集中,我们只需要引用就好,没有的,请到此处下载

        在实现之前,我们需要先在表现层创建一个Resource文件夹,用于存放我们公共的文件、图片及模板等,然后下载

    IPScaner.zip,并加压到Resource文件夹下。

        QQwry.dat 纯真IP数据库收集了包括中国电信、中国网通、长城宽带、网通宽带、聚友宽带等 ISP 的最新准确 IP 地址数据。目前该库不是最新的数据,大家可以到网上下载到该目录下,这在我们做登录日志时可用到。

    一、我们在区域BackstageModule下创建Login的控制器和视图:

    (1)LoginController.cs控制器

    using Bobo.Utilities;
    using Bobo.Utilities.Membership;
    using IA.Business.SystemBusiness;
    using IA.Entity;
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace IA.WebApp.Areas.BackstageModule.Controllers
    {
        /// <summary>
        /// 后台登录控制器
        /// </summary>
        public class LoginController : Controller
        {
            //
            // GET: /BackstageModule/Login/
    
            public ActionResult Index()
            {
                return View();
            }
            /// <summary>
            /// 登录 
            /// </summary>
            /// <param name="Account"></param>
            /// <param name="Password"></param>
            /// <param name="Code"></param>
            /// <returns></returns>
            public ActionResult SubmitLogin(string Account, string Password, string Code)
            {
                try
                {
                    Code = Md5Helper.CreateMd5(Code.ToLower(), 16);
                    if (Session["session_Userloginvcode"].ToString() != Code)
                    {
                        return Content(new JsonMessage { Success = false, Code = "-2", Message = "验证码不正确" }.ToString());
                    }
                    if (string.IsNullOrEmpty(Account) || string.IsNullOrEmpty(Password))
                    {
                        return Content(new JsonMessage { Success = false, Code = "-1", Message = "用户名或密码错误!" }.ToString());
                    }
                    IPScanerHelper objScan = new IPScanerHelper();
                    string IPAddress = NetHelper.LANIP;
                    objScan.IP = IPAddress;
                    objScan.DataPath = Server.MapPath("~/Resource/IPScaner/QQWry.Dat");
                    string IPAddressName = objScan.IPLocation();
    
                    int IsOk = new Base_UserBll().UserLogin(Account, Password, IPAddressName, IPAddress);
                    string strCode = "-1";
                    string Message = "";
                    string czMsg = "";
                    bool Success = false;
                    switch (IsOk)
                    {
                        case 1:
                            strCode = "1";
                            Message = "登录成功!";
                            czMsg = "登录成功!";
                            Success = true;
                            break;
                        case 2:
                            strCode = "-1";
                            Message = "登录失败,用户名或密码错误!";
                            czMsg = "密码错误!";
                            Success = false;
                            break;
                        case 3:
                            strCode = "-1";
                            Message = "登录失败,用户名或密码错误!";
                            czMsg = "账号不存在!";
                            Success = false;
                            break;
                    }
                    Base_SysLogBll.Instance.WriteLog(Account, OperationType.Login, strCode, czMsg + "、IP所在城市:" + IPAddressName);
                    return Content(new JsonMessage { Success = Success, Code = strCode, Message = Message }.ToString());
                }
                catch (Exception ex)
                {
                    return Content(new JsonMessage { Success = false, Code = "-1", Message = "操作失败:" + ex.Message }.ToString());
                }
    
            }
            /// <summary>
            /// 验证码
            /// </summary>
            /// <returns></returns>
            public ActionResult VerifyCode()
            {
                int codeW = 80;
                int codeH = 22;
                int fontSize = 16;
                string chkCode = string.Empty;
                //颜色列表,用于验证码、噪线、噪点 
                Color[] color = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };
                //字体列表,用于验证码 
                string[] font = { "Times New Roman", "Verdana", "Arial", "Gungsuh", "Impact" };
                //验证码的字符集,去掉了一些容易混淆的字符 
                char[] character = { '2', '3', '4', '5', '6', '8', '9', 'a', 'b', 'd', 'e', 'f', 'h', 'k', 'm', 'n', 'r', 'x', 'y', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W', 'X', 'Y' };
                Random rnd = new Random();
                //生成验证码字符串 
                for (int i = 0; i < 4; i++)
                {
                    chkCode += character[rnd.Next(character.Length)];
                }
                //写入Session、验证码加密
                Session["session_Userloginvcode"] = Md5Helper.MD5(chkCode.ToLower(), 16);
                //创建画布
                Bitmap bmp = new Bitmap(codeW, codeH);
                Graphics g = Graphics.FromImage(bmp);
                g.Clear(Color.White);
                //画噪线 
                for (int i = 0; i < 1; i++)
                {
                    int x1 = rnd.Next(codeW);
                    int y1 = rnd.Next(codeH);
                    int x2 = rnd.Next(codeW);
                    int y2 = rnd.Next(codeH);
                    Color clr = color[rnd.Next(color.Length)];
                    g.DrawLine(new Pen(clr), x1, y1, x2, y2);
                }
                //画验证码字符串 
                for (int i = 0; i < chkCode.Length; i++)
                {
                    string fnt = font[rnd.Next(font.Length)];
                    Font ft = new Font(fnt, fontSize);
                    Color clr = color[rnd.Next(color.Length)];
                    g.DrawString(chkCode[i].ToString(), ft, new SolidBrush(clr), (float)i * 18 + 2, (float)0);
                }
                //将验证码图片写入内存流,并将其以 "image/Png" 格式输出 
                MemoryStream ms = new MemoryStream();
                try
                {
                    bmp.Save(ms, ImageFormat.Png);
                    return File(ms.ToArray(), @"image/Gif");
                }
                catch (Exception)
                {
                    return null;
                }
                finally
                {
                    g.Dispose();
                    bmp.Dispose();
                }
            }
    
            /// <summary>
            /// 退出当前登录,清空所有用户cookie
            /// </summary>
            /// <returns></returns>
            public ActionResult LoginOut()
            {
                /*****************************************
                 * 采用双cookie登录,则需要释放双cookie
                 * 标准cookie记录用户主要信息,附加cookie用于前台
                 * 附加cookie可记录自定义的任何信息
                 * ***************************************/
                //清空当前登录用户信息
                ManageProvider.Provider.EmptyCurrent();
                ManageProvider.Provider.EmptyCurrent<Base_User>();
                Session.Abandon();  //取消当前会话
                Session.Clear();    //清除当前浏览器所以Session
                return Content("1");
            }
        }
    }

    (2)Index视图

    @{
        ViewBag.Title = "登录";
       
    }
    <script src="~/Content/Scripts/jquery/jquery-1.8.2.min.js"></script>
    <script src="~/Content/Scripts/jquery.form.js"></script>
    <script src="~/Content/Scripts/boboui-jshelp.js"></script>
    <script src="~/Content/Scripts/validator/boboui-validator.js"></script>
    <script src="~/Content/Scripts/layer/layer.js"></script>
    <script src="~/Content/Scripts/jQuery.md5.js"></script>
    <link href="~/Content/Styles/base.css" rel="stylesheet" />
    <link href="~/Content/Styles/main.css" rel="stylesheet" />
    <body style="background-color: #4e95e5; " class="font-yahei">
        <div class="mainBox">
            <h1 style="text-align: center; font-weight: bold; font-size:24px; color: #fff; padding-bottom: 25px; letter-spacing: 2px;">枼落NO.1</h1>
            <div class="Dialog-Box BoxS" style="margin: 0 auto; max- 500px; max-height: 300px; background-color: #fff; border-radius: 4px; padding: 0;">
                <div class="Dialog-Tit-com" style="position:relative">系统用户登录</div>
                <div class="login-Ico L"><img src="~/Content/Images/slice/users_03.png" width="78" height="76" /> </div>
                <div class="login-box L">
                    <form id="form1" action="/BackstageModule/Login/SubmitLogin" method="post" enctype="multipart/form-data" style="margin: 1px">
                        <table class="layer-table-form">
                            <tr>
                                <td><span class="layer-form-tit">用户名:</span><input style="height:30px;border-radius:4px;" type="text" name="Account" class="layer-form-txt" id="Account" datacol="yes" err="用户名" checkexpession="NotNull" /></td>
                            </tr>
                            <tr>
                                <td><span class="layer-form-tit">密 &nbsp;&nbsp;码:</span><input style="height:30px;border-radius:4px;" type="password" name="Password" class="layer-form-txt" id="Password" datacol="yes" err="密码" checkexpession="NotNull" /></td>
                            </tr>
                            <tr>
                                <td>
                                    <span class="layer-form-tit">验证码:</span><input type="text" name="Code" style=" 100px; height: 30px; border-radius: 4px; " class="layer-form-txt" id="Code" datacol="yes" err="验证码" checkexpession="NotNull" />
                                    <img id="codeImg" src="/BackstageModule/Login/VerifyCode" data-url="/BackstageModule/Login/VerifyCode" alt="点击切换验证码" onclick="switchCode($(this))" />
                                </td>
                            </tr>
                        </table>
                    </form>
                </div>
                <div class="Dialog-sub-com" style="position:relative">
                    <input type="button" value="登录" class="Dialog-btn subBtn" onclick="AcceptClick()">
                    <input type="button" value="取消" class="Dialog-btn extBtn" onclick="selfClose()">
                </div>
            </div>
        </div>
        <div class="clear" style="position:fixed;bottom:10px;color:#fff;text-align:center;100%;">页落素材网 Copyright 2008-2018 All Rights Reserved</div>
    </body>
    
    <script type="text/javascript">
        //提交表单
        function AcceptClick() {
            if (!CheckDataValid('#form1', true)) {
                return false;
            }
    
            var postData = GetWebControls("#form1");
            postData.Password = escape($.md5(postData.Password));
            $.post("/BackstageModule/Login/SubmitLogin?Code=" + $("#Code").val(), postData, function (data) {
                layer.msg(data.Message, { icon: data.Code, time: 1000 }, function () {
                    if (data.Code > 0) {
                        selfClose();
                        location.href = "/BackstageModule/ArticleMange/Index";
                    }
                    else if (data.Code == -2) {
                        $("#Code").val("").focus();
                        switchCode($("#codeImg"));
                    }
                });
            }, "json");
        }
        //回车键
        document.onkeydown = function (e) {
            if (!e) e = window.event; //火狐中是 window.event
            if ((e.keyCode || e.which) == 13) {
                AcceptClick();
            }
        }
        //自定义关闭窗口
        function selfClose() {
            var index = parent.layer.getFrameIndex(window.name);
            parent.layer.close(index);
        }
        //切换验证码
        function switchCode(obj) {
            var url = obj.attr("data-url");
            url += "?date=" + new Date().toString();
            obj.attr("src", url);
        }
    </script>

        二、在完成登录操作的过程后,我们需要对登录权限的认证,也就是非登录不可访问。

        首先我们需要在表现层中的SystemExtension文件夹中添加LoginAuthorizeAttribute.cs和ManagerPermissionAttribute.cs登录权限类:

        (1)LoginAuthorizeAttribute.cs

    using Bobo.Utilities;
    using Bobo.Utilities.Membership;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace IA.WebApp.SystemExtension
    {
        /// <summary>
        /// 登录权限认证
        /// </summary>
        public class LoginAuthorizeAttribute : AuthorizeAttribute
        {
            //地址参数的绝对路径("~/aaa/vvv")
            private String _LoginUrl = String.Empty;
            //无参构造器
            public LoginAuthorizeAttribute() { }
    
            /// <summary>
            /// 标记构造器,可传入登陆地址
            /// </summary>
            /// <param name="LoginUrl">地址参数的绝对路径("~/aaa/vvv")</param>
            public LoginAuthorizeAttribute(string LoginUrl)
            {
                this._LoginUrl = LoginUrl;
            }
            /// <summary>
            /// 响应前执行验证,查看当前用户是否有效 
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
                var areaName = filterContext.RouteData.DataTokens["area"];
                var controllerName = filterContext.RouteData.Values["controller"];
                var action = filterContext.RouteData.Values["Action"];
                var returnUrl = filterContext.RequestContext.HttpContext.Request.Url.ToString();
                if (!StringHelper.IsNullOrEmpty(this._LoginUrl) && this._LoginUrl.IndexOf('?') == -1)
                {
                    this._LoginUrl += ("?ReturnUrl=" + StringHelper.Escape(returnUrl));
                }
                if (this._LoginUrl.IndexOf("BackstageModule") != -1)
                {
                    if (!ManageProvider.Provider.IsOverdue())
                    {
                        filterContext.Result = new RedirectResult(this._LoginUrl);
                    }
                    else
                    {
                        if (ManageProvider.Provider.Current().Code != "System")
                        {
                            filterContext.Result = new RedirectResult(this._LoginUrl);
                        }
                    }
                }
                else
                {
    
                    //登录是否过期
                    if (!ManageProvider.Provider.IsOverdue())
                    {
                        filterContext.Result = new RedirectResult(this._LoginUrl);
                    }
                    else
                    {
                        if (ManageProvider.Provider.Current().Code == "System")
                        {
                            filterContext.Result = new RedirectResult(this._LoginUrl);
                        }
                    }
                }
            }
        }
    }

        (2)ManagerPermissionAttribute.cs

    using Bobo.Utilities;
    using Bobo.Utilities.Membership;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace IA.WebApp.SystemExtension
    {
        public class ManagerPermissionAttribute : AuthorizeAttribute
        {
            private PermissionMode _CustomMode;
            /// <summary>默认构造</summary>
            /// <param name="Mode">权限认证模式</param>
            public ManagerPermissionAttribute(PermissionMode Mode)
            {
                _CustomMode = Mode;
            }
            /// <summary>权限认证</summary>
            /// <param name="filterContext"></param>
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
                //登录权限认证
                if (!ManageProvider.Provider.IsOverdue())
                {
                    filterContext.Result = new RedirectResult("~/Login/Default");
                }
                //防止被搜索引擎爬虫、网页采集器
                if (!this.PreventCreeper())
                {
                    filterContext.Result = new RedirectResult("~/Login/Default");
                }
                //权限拦截是否忽略
                if (_CustomMode == PermissionMode.Ignore)
                {
                    return;
                }
                //执行权限认证
                if (!this.ActionAuthorize(filterContext))
                {
                    ContentResult Content = new ContentResult();
                    Content.Content = "<script type='text/javascript'>top.Loading(false);alert('很抱歉!您的权限不足,访问被拒绝!');</script>";
                    filterContext.Result = Content;
                }
            }
            /// <summary>
            /// 执行权限认证
            /// </summary>
            /// <returns></returns>
            private bool ActionAuthorize(AuthorizationContext filterContext)
            {
                if (ManageProvider.Provider.Current().IsSystem && ManageProvider.Provider.Current().CompanyCategory != "SystemUnit")
                    return true;
                var areaName = filterContext.RouteData.DataTokens["area"] + "/";            //获取当前区域
                var controllerName = filterContext.RouteData.Values["controller"] + "/";    //获取控制器
                var action = filterContext.RouteData.Values["Action"];                      //获取当前Action
                string requestPath = "/" + areaName + controllerName + action;              //拼接构造完整url
                string ModuleId = DESEncrypt.Decrypt(CookieHelper.GetCookie("ModuleId"));
                //bool Result = Base_ModulePermissionBll.Instance.ActionAuthorize(requestPath.ToLower(), ManageProvider.Provider.Current().ObjectId, ModuleId, ManageProvider.Provider.Current().UserId);
                return true;// Result;
            }
            /// <summary>
            /// CA验证方法
            /// </summary>
            /// <param name="filterContext"></param>
            /// <returns></returns>
            private bool ActionCA(AuthorizationContext filterContext)
            {
                //TODO:如何在过滤器调用CA的前台检测方法返回值(NC)
                if (ManageProvider.Provider.Current().IsSystem && ManageProvider.Provider.Current().CompanyCategory != "SystemUnit")
                {
                    return true;
                }
                else
                {
                    return true;
                }
            }
            /// <summary>
            /// 防止被搜索引擎爬虫、网页采集器
            /// </summary>
            /// <returns></returns>
            private bool PreventCreeper()
            {
                return true;
            }
        }
    }

    权限认证做好后,我们在需要权限认证的控制器上加上[LoginAuthorize("~/BackstageModule/Login/Index")]这句了,例如文章控制器:

    19.png

    然后改造公共布局页_LayoutMange.cshtml:

    @using Bobo.Utilities.Membership
    @using IA.Business
    <!DOCTYPE html>
    <html>
    @*后台公共模块*@
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
        <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" media="screen" />
        <link href="~/Content/Styles/main.css" rel="stylesheet" />
        <link href="~/Content/Styles/base.css" rel="stylesheet" />
        <script src="~/Content/Scripts/datepicker/WdatePicker.js"></script>
        <script src="~/Content/Scripts/jquery/jquery-1.8.2.min.js"></script>
        <script src="~/Content/Scripts/jquery.form.js"></script>
        <script src="~/Content/Scripts/boboui-jshelp.js"></script>
        <script src="~/Content/Scripts/validator/boboui-validator.js"></script>
        <script src="~/Content/Scripts/layer/layer.js"></script>
        <script src="~/Content/Scripts/Juicer/juicer.js"></script>
        <script src="~/Content/Scripts/m_pager.js"></script>
    </head>
    <body class="set_body">
        <div class="w_header font-yahei">
            <div class="header-item">
                <div class="mAuto">
                    <div class="L">页落素材网 - 用户管理后台   【当前用户】:@ManageProvider.Provider.Current().UserName</div>
                    <div class="R"><a href="javascript:;" id="LoginOut" style="color: #00b7f0;">【退出登录】</a></div>
                </div>
            </div>
            <div class="header-nav clear">
                <div class="mAuto">
                    <a href="/" class="logo L"> <img src="~/Content/Images/slice/logoMange.png" /></a>
                    <ul class="R nav-item">
                        <li class="L"><a href="/BackstageModule/Article/Index" class="wzgl">网站管理</a></li>
                        <li class="L"><a href="/BackstageModule/TrainSignupInfo/Index" class="hypx">区块链</a></li>
                        <li class="L"><a href="/BackstageModule/MemberManagement/Index" class="hygl">人工智能</a></li>
                        <li class="L"><a href="/">返回首页</a></li>
                    </ul>
                </div>
            </div>
        </div>
    
        @RenderBody()
        <div id="footer">
            <div class="foot-tip w_footer">
                <div class="webPage text-center">
                    页落素材网是网页特效下载社区,以提高效率、分享经验的理念,提供高品质实用、简单、易懂的Web页面特效。
                </div>
            </div>
        </div>
    
        <script type="text/javascript">
            $(function () {
                $("#LoginOut").on("click", function () {
                    AjaxJson("/BackstageModule/Login/LoginOut", {}, function (data) {
                        layer.msg("您已退出登录,欢迎再来哦 ^_^", { icon: 6, shade: [0.3, '#000'] }, function () {
                            location.href = "/BackstageModule/Login/Index";
                        });
                    });
                });
            })
            //复选框选定事件
            function change(obj) {
                var tr = obj.parentElement.parentElement;
                if (obj.checked) {
                    tr.style.backgroundColor = '#e5eaff';
                    tr.style.borderColor = '#cacccb';
                } else {
                    tr.style.backgroundColor = '#fff';
                }
            }
        </script>
        @RenderSection("scripts", required: false)
    </body>
    </html>

    登录效果图预览

    localhost_7096_BackstageModule_login_Index.png

  • 相关阅读:
    Freemarker list的使用
    Java通过流对MP4视频文件进行加密,H5 video播放流
    阿里云API公共参数的获取
    javah找不到类文件
    Java调用打印机打印指定路径图片
    Java绘制图片并进行合成
    Java生成二维码和解析二维码URL
    计算机网络第六版知识大纲
    Linux安装mysql mysql5.5.40 <NIOT>
    rsync unison+inotify双向实时同步
  • 原文地址:https://www.cnblogs.com/boyzi/p/9963783.html
Copyright © 2011-2022 走看看