亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

分享一個html+js+ashx+easyui+ado.net權限管理系統

2019-11-15 02:31:32
字體:
來源:轉載
供稿:網友

分享一個html+js+ashx+easyui+ado.net權限管理系統

EasyUI、權限管理 這是個都快被搞爛了的組合,但是easyui的確好用,權限管理在項目中的確實用。一直以來博客園里也不少朋友分享過,但是感覺好的要不沒源碼,要不就是過度設計寫的太復雜看不懂,也懶得去看懂,還有一些不是在推廣自己的代碼生成器就是在賣權限組件,看著漂亮的UI和完善的功能就是沒源碼學習,真是惱人。

前段時間公司項目階段性結束了,就抽空把權限控制的部分抽取出來寫了個html+js+ashx+ado.net的權限管理系統分享給一些初學者,這個權限系統demo沒有MVC、沒有ORM、數據庫表都沒設外鍵關系、級聯刪除等,所有需要級聯操作的地方都是事務提交。界面上的所有操作基本都是jquery發Ajax請求ashx處理,ashx處理后輸出json前臺接收處理并配合easyui的組件響應給用戶?;緵]什么門檻,比較適合初學者。先看項目結構圖:

項目結構基本就是模仿PetShop的,簡單的7層,接口里定義方法,不同數據庫不同實現,工廠負責創建訪問數據庫的對象,具體訪問哪個數據庫寫在配置文件,都是老東西了也沒什么說的。Model、BLL、SQLServerDAL等類庫里的類都跟數據庫表名保持一致,新建類庫的時候修改了默認的命名空間(右鍵類庫 - 屬性 - 應用程序 - 程序集名稱&默認命名空間),調用的時候用解決方案名.類庫名.類名,這是我的個人習慣。具體查看源碼

接下來簡單分享下代碼和貼圖演示,懶的聽我啰嗦的直接跳轉到文章結尾下載源碼。戳我

一、關于登陸

登陸就是用框架提供的FormsAuthentication類來做的,基本就是寫cookie了,用戶登錄成功就加密下票證寫到cookie里,簡單的SetAuthCookie方法有點太簡單了,只能寫用戶名到cookie里。我一般用FormsAuthenticationTicket類來做,可以把整個用戶對象(userData)都寫到cookie里。如果只把用戶名寫到cookie里,這樣用戶在別的瀏覽器登錄然后執行修改密碼操作,過來之前登陸過的瀏覽器,雖然改了密碼,但還是可以繼續保持登陸狀態(博客園就是),這顯然不符合常理。我的是把用戶名和密碼都保存到cookie里,然后用戶每次訪問都取出用戶名和密碼去數據庫驗證,如果找不到記錄就干掉cookie。說到這肯定有人疑惑,把用戶密碼寫到cookie里會不會不安全,用戶密碼本身就是不可逆的md5,寫入cookie之前也再次進行了加密,我個人相信是比較安全的,且只有你自己看到cookie,如果擔心有人抓包,可以把登陸功能部署到https上(個人想法,歡迎拍磚)。

簡單來說,我的登陸邏輯:用戶訪問登陸頁面就ajax請求后臺驗證cookie,只有用戶名和密碼匹配上(用戶沒修改密碼)、狀態IsAble可用(管理員沒在后臺禁用此用戶)等等的情況下直接跳到首頁,其他都干掉cookie。這樣做的好處就是管理員可以很方便的控制一個用戶的狀態,就算他保存了cookie,因為服務端每次都有驗證IsAble字段,管理員也可以很方便的禁用這個用戶。還有不影響登陸的情況:比如用戶修改了自己的姓名等情況也得重寫cookie,否則從cookie里取出來的用戶名顯示到歡迎區域就不準確了,這里用FormsAuthenticationTicket就完美了,userData參數可以存很多東西。

首次訪問登陸頁面判斷是否登陸和用戶點擊登陸按鈕的示例代碼:

case "iflogin":    //System.Threading.Thread.Sleep(5000);    if (context.Request.IsAuthenticated)    {        FormsIdentity id = (FormsIdentity)context.User.Identity;        FormsAuthenticationTicket tickets = id.Ticket;        //獲取票證里序列化的用戶對象(反序列化)        ZGZY.Model.User userCheck = new javaScriptSerializer().Deserialize<ZGZY.Model.User>(tickets.UserData);        //執行登錄操作        ZGZY.Model.User userReLogin = new ZGZY.BLL.User().UserLogin(userCheck.UserId, userCheck.UserPwd);        if (userReLogin == null)        {            FormsAuthentication.SignOut();            context.Response.Write("{/"msg/":/"用戶名或密碼錯誤!/",/"success/":false}");        }        else if (!userReLogin.IsAble)        {            FormsAuthentication.SignOut();            context.Response.Write("{/"msg/":/"用戶已被禁用!/",/"success/":false}");        }        else        {            //記錄登錄日志            ZGZY.Model.LoginLog loginInfo = new Model.LoginLog();            loginInfo.UserIp = context.Request.UserHostAddress;            loginInfo.City = context.Request.Params["city"] ?? "未知";   //訪問者所處城市            loginInfo.UserName = context.User.Identity.Name;            loginInfo.Success = true;            new ZGZY.BLL.LoginLog().WriteLoginLog(loginInfo);            context.Response.Write("{/"msg/":/"已登錄過,正在跳轉!/",/"success/":true}");        }    }    else        context.Response.Write("{/"msg/":/"nocookie/",/"success/":false}");    break;case "login":    //System.Threading.Thread.Sleep(5000);    string userIp = context.Request.UserHostAddress;    string city = context.Request.Params["city"] ?? "未知";    string remember = context.Request.Params["remember"] ?? "";   //記住密碼天數    string name = context.Request.Params["loginName"];    string pwd = ZGZY.Common.Md5.GetMD5String(context.Request.Params["loginPwd"]);  //md5加密    DateTime? lastLoginTime;    if (new ZGZY.BLL.LoginLog().CheckLogin(userIp, out lastLoginTime) != null)    {        DateTime dtNextLogin = Convert.ToDateTime(lastLoginTime);        context.Response.Write("{/"msg/":/"密碼錯誤次數達到5次,請在" + dtNextLogin.AddMinutes(30).ToShortTimeString() + "之后再登陸!/",/"success/":false}");    }    else    {        ZGZY.Model.LoginLog loginInfo = new Model.LoginLog();        loginInfo.UserName = name;        loginInfo.UserIp = userIp;        loginInfo.City = city;        ZGZY.Model.User currentUser = new ZGZY.BLL.User().UserLogin(name, pwd);        if (currentUser == null)        {            context.Response.Write("{/"msg/":/"用戶名或密碼錯誤!/",/"success/":false}");            loginInfo.Success = false;            new ZGZY.BLL.LoginLog().WriteLoginLog(loginInfo);        }        else if (currentUser.IsAble == false)        {            context.Response.Write("{/"msg/":/"用戶已被禁用!/",/"success/":false}");            loginInfo.Success = false;            new ZGZY.BLL.LoginLog().WriteLoginLog(loginInfo);        }        else        {            //記錄登錄日志            loginInfo.Success = true;            new ZGZY.BLL.LoginLog().WriteLoginLog(loginInfo);            context.Response.Write("{/"msg/":/"登錄成功!/",/"success/":true}");            DateTime dateCookieExpires;  //cookie有效期            switch (remember)            {                case "notremember":                    dateCookieExpires = new DateTime(9999, 12, 31);   //默認時間                    break;                case "oneday":                    dateCookieExpires = DateTime.Now.AddDays(1);                    break;                case "sevenday":                    dateCookieExpires = DateTime.Now.AddDays(7);                    break;                case "onemouth":                    dateCookieExpires = DateTime.Now.AddDays(30);                    break;                case "oneyear":                    dateCookieExpires = DateTime.Now.AddDays(365);                    break;                default:                    dateCookieExpires = new DateTime(9999, 12, 31);                    break;            }            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket            (                2,                currentUser.UserId,                DateTime.Now,                dateCookieExpires,                false,                new JavascriptSerializer().Serialize(currentUser)  //序列化當前用戶對象            );            string encTicket = FormsAuthentication.Encrypt(ticket);            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);            if (dateCookieExpires != new DateTime(9999, 12, 31))    //不是默認時間才設置過期時間,否則會話cookie                cookie.Expires = dateCookieExpires;            context.Response.Cookies.Add(cookie);        }    }    break;

博客園的做法是訪問登陸頁面就把cookie干掉(如果有),我個人還是覺得有cookie再訪問登陸頁面就跳轉到首頁比較好。你可以訪問博客園的登陸頁面試試(慎點,會干掉你的cookie)

另外登陸功能還調用了sina的api獲取用戶登錄城市、同一個ip連續5次輸錯密碼就30分鐘之內不讓登陸,詳細請自己查看源碼。

二、權限控制

權限控制基本就是用戶擁有角色(可以多角色)、角色擁有菜單不同按鈕的權限(瀏覽、增加、修改、刪除等)。這樣基本做到了單用戶多角色,界面上的操作按鈕根據用戶擁有的權限顯示或者不顯示。先添加一個用戶,默認密碼123:

"已經改密"如果不勾選上,那么下次這個用戶登錄就會彈框讓他修改密碼(這個功能是跟添加用戶默認密碼是123相互呼應的)。直接用添加的用戶登錄會什么都沒有,因為此用戶沒有任何菜單權限:

左側的目錄樹是EasyUI的Tree組件,打開頁面的時候ajax取出當前用戶擁有的菜單權限然后展示出來,不同用戶看到的菜單是不一樣的。后臺操作基本就是一個連表查詢,DataTable取出來然后遍歷構建這個Tree:

/// <summary>/// 根據用戶主鍵id查詢用戶可以訪問的菜單/// </summary>public DataTable GetUserMenu(int id){    StringBuilder strSql = new StringBuilder();    strSql.Append("select distinct(m.Name) menuname,m.Id menuid,m.Icon icon,u.Id userid,u.UserId username,m.ParentId menuparentid,m.Sort menusort,m.LinkAddress linkaddress from tbUser u");    strSql.Append(" join tbUserRole ur on u.Id=ur.UserId");    strSql.Append(" join tbRoleMenuButton rmb on ur.RoleId=rmb.RoleId");    strSql.Append(" join tbMenu m on rmb.MenuId=m.Id");    strSql.Append(" where u.Id=@Id order by m.ParentId,m.Sort");    return ZGZY.Common.SqlHelper.GetDataTable(ZGZY.Common.SqlHelper.connStr, CommandType.Text, strSql.ToString(), new SqlParameter("@Id", id));}

重新登陸下管理員賬戶添加一個瀏覽角色:

給角色授權:

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品电影在线观看| 国产丝袜一区二区三区免费视频| 国产脚交av在线一区二区| 亚洲成av人影院在线观看| 第一福利永久视频精品| 中文字幕在线国产精品| 亚洲欧美国产精品久久久久久久| 欧美性xxxx18| 日本在线精品视频| 国产精品亚洲美女av网站| 亚洲成人性视频| 欧美日韩亚洲精品一区二区三区| 98视频在线噜噜噜国产| 欧美久久久精品| 狠狠色狠狠色综合日日小说| 一区二区三区亚洲| 欧美激情在线播放| 日韩美女av在线免费观看| 亚洲欧美日韩视频一区| 亚洲电影免费观看高清完整版| 亚洲人成网站免费播放| 国产成人精品久久二区二区91| 日韩欧美国产激情| 91免费视频国产| 色婷婷综合成人av| 456亚洲影院| 日韩不卡在线观看| 国产成人精品av在线| 亚洲黄色免费三级| 国产视频丨精品|在线观看| 国产主播欧美精品| 日韩精品福利网站| 国产亚洲欧洲黄色| 热久久免费视频精品| 欧美精品免费在线观看| 亚洲精品短视频| 在线视频中文亚洲| 久久久国产成人精品| 久久激情视频免费观看| 亚洲美女中文字幕| 91免费版网站入口| 久久手机免费视频| xx视频.9999.com| 午夜精品一区二区三区在线| 国产精品入口夜色视频大尺度| 亚洲视频欧洲视频| 日韩精品在线观看视频| 激情懂色av一区av二区av| 欧美激情va永久在线播放| 亚洲人a成www在线影院| 亚洲高清色综合| 中文字幕久热精品在线视频| 美女av一区二区三区| 欧美日本高清视频| 久久久精品2019中文字幕神马| 91在线免费看网站| 久久九九国产精品怡红院| 久久久噜噜噜久噜久久| 日韩在线高清视频| 亚洲欧洲日本专区| 欧美成人黑人xx视频免费观看| 国产精品一区二区三| 免费91麻豆精品国产自产在线观看| 国产精品流白浆视频| 欧美电影免费播放| 国产成人福利视频| 日本久久亚洲电影| 欧美亚洲国产视频| 亚洲美女中文字幕| 91精品国产91久久| 一区二区三区亚洲| 欧美裸体xxxxx| 中文字幕亚洲在线| 国产精品91久久久| 精品国产福利在线| 亚洲精品456在线播放狼人| 成人有码在线播放| 久久久久久久影院| 亚洲综合成人婷婷小说| 富二代精品短视频| 日韩欧美在线视频免费观看| 精品国产福利视频| 国产成人精品a视频一区www| 成人午夜两性视频| 欧美性猛交xxxx乱大交3| 免费不卡在线观看av| 亚洲人成亚洲人成在线观看| 成人激情视频网| 亚洲国产精品va在线观看黑人| 国产精品自在线| www.亚洲人.com| 欧美激情2020午夜免费观看| 欧美日韩国产一中文字不卡| 日韩电影中文字幕在线| 国产在线精品成人一区二区三区| 久久精品99久久香蕉国产色戒| 欧美日韩一区二区免费视频| 国产欧美亚洲视频| 亚洲精品久久久久中文字幕二区| 亚洲www视频| 午夜精品蜜臀一区二区三区免费| 欧美精品久久久久久久| 亚洲国产成人av在线| 4k岛国日韩精品**专区| 欧美电影免费看| 国产成人精品电影久久久| 国产一区二区在线播放| 中文字幕亚洲一区二区三区五十路| 热re91久久精品国99热蜜臀| 亚洲福利精品在线| 国产精品久久久久久久久久免费| 久久视频免费在线播放| 色狠狠av一区二区三区香蕉蜜桃| 日韩中文字幕在线观看| 成人激情在线观看| 亚洲天堂av女优| 久久精品美女视频网站| 美女av一区二区三区| 91色精品视频在线| 欧美精品videos性欧美| 亚洲第一男人天堂| 中文字幕日韩精品有码视频| 亚洲欧美第一页| 亚洲国产精品高清久久久| 精品久久久精品| 国产精品亚洲美女av网站| 国产成人激情视频| 久久久久久久电影一区| 亚洲视频一区二区三区| 精品国产区一区二区三区在线观看| 色av中文字幕一区| 欧美尺度大的性做爰视频| 国产精品老女人精品视频| 国产91色在线| 日韩成人网免费视频| 亚洲最大成人在线| 日本久久久久久久久久久| 国产精品九九九| 97视频在线观看亚洲| 久热精品视频在线| 国产91免费看片| 国产亚洲精品久久久久久777| 2019国产精品自在线拍国产不卡| 中文字幕精品一区久久久久| 亚洲最大av在线| 欧美一级视频一区二区| 久久久免费高清电视剧观看| 国产精品99一区| 欧美日韩亚洲视频| 亚洲开心激情网| 国产成人综合精品在线| 91av国产在线| 亚洲成人av片在线观看| 欧美日韩免费区域视频在线观看| 国产成人精品在线| 欧美日韩国产在线播放| 国产精品久久久久久久电影| 欧美电影免费在线观看| 一夜七次郎国产精品亚洲| 福利一区福利二区微拍刺激| 国产精品1234| 国产精品欧美一区二区三区奶水| 久久久在线免费观看| 欧美大尺度电影在线观看|