每一個網站、APP都幾乎必然有其管理後臺,其中管理的內容則是公司的核心技術財產。而登陸模塊則是這扇大門,其安全的重要性可想而知。咱們知道,功能越多,安全性就會越低,因此咱們有必要從新審視一下,管理後臺的登陸界面到底須要些什麼功能。html
一、基本的帳號密碼登陸。這個無可避免是必然須要的了。前端
二、圖片驗證碼。驗證碼的目的是爲了阻止機器人暴力撞庫,做爲管理後臺頗有必要,並且是要每次登陸請求都需從新驗證。jquery
三、填完用戶名或密碼時,Ajax實時驗證。這個功能常見於一些自動管理後臺的註冊模塊,用於驗證用戶名是否已被佔用。但此功能一般會致使不需通過驗證碼驗證,從而使得暴力撞庫有隙可乘。ajax
四、記住我選項。這是一個使用cookie記住登陸用戶的功能,使用戶下次再來時能夠不須要再登陸便可經過驗證。但cookie必然須要記錄 用戶ID或用戶名 相關的信息,存在瀏覽器中,有必定的CSRF攻擊風險和信息泄漏風險。數據庫
五、找回密碼功能。這是一個高危功能,不管是邏輯疏漏仍是安全不嚴謹,都會致使帳號的失竊。參考1月份支付寶找回密碼的危機。因此建議作法是,公司文檔保存相關的帳號密碼信息,如遇實在沒法登陸,則找技術人員進入數據庫修改密碼(加密後)。後端
六、註冊功能。這個不要作在外面,在後臺的功能里加一個添加用戶會安全不少。瀏覽器
七、第三方登陸。如QQ登陸、微信登陸?不須要,你們都知道QQ很容易被盜號,不宜做爲安全性要求高的系統的登陸入口。微信則須要拿手機出來掃碼,不如直接輸入密碼來得方便,另外它還須要申請微信公衆號以及500塊每一年的公衆號認證費用。安全
綜上,得出一個夠用、安全的管理後臺的登陸界面微信
一、驗證碼安全。以AJAX提交爲例,每次嘗試登陸後,不管是否登陸成功,後端都要註銷當前驗證碼SESSION,前端JS刷新驗證碼。後臺要註銷SESSION是以避免黑客屏蔽JS致使驗證碼只需一寫次,從而致使爆庫。cookie
二、網絡傳輸安全。最好使用https加密,以避免網絡傳輸過程泄露帳號密碼,如在咖啡店等他人WIFI環境。若是沒有使用HTTPS,則應該在前端JS加密登陸名和密碼,後端再解密。由於JS是明文的,因此要使用非對稱性加密(如RSA),JS使用公鑰加密,服務端使用私鑰解密。甚至對JS文件自己也能夠做一些加密壓縮。爲何登陸名也要加密呢?仍是避免信息泄露,以避免別人根據登陸名猜出密碼。
三、登陸成功時從新生成SESSION_ID。主要是爲了防止固定會話ID的CSRF攻擊。
知己知彼,戰鬥才能勝利。上面這些功能和安全,都是一些通用的防守攻擊套路。但敵人在暗我在明,敵人何時派出過特務,何時發出過攻擊,發起了什麼樣的攻擊?僅經過上面的功能,咱們無從得知。因此,咱們還須要一個監控器--登陸日誌。
而後這個登陸日誌,咱們須要記錄些什麼東西呢? 登陸名、是否成功、IP地址、時間。可是,這還不夠,這樣咱們只能分析到了是誰有攻擊咱們,可是分析不到他是經過什麼方式來攻擊。那還要記錄什麼呢?URL地址(含GET數據)、POST數據。但須要注意的是,咱們登陸時的密碼也在POST數據裏,切不可將密碼存儲在登陸日誌裏,即便是RSA加密過的也不行,應以***星號代替,不然這和明文存儲密碼沒什麼差異。
前端代碼的要點是登陸時RSA加密帳號密碼,使用的是 jsencrypt.js 庫,Ajax提交表單用的是 jquery.form.js 。核心代碼以下,須要注意的是,ajaxForm接受的這兩個回調函數,參數名是固定的沒法修改,修改表單數據用的是formData,提交成功回調的結果名是responseText。標紫色的兩個變量是後臺輸出的模板變量。
//AJAX提交登陸表單 $(function(){ var formSubOpt = { beforeSubmit: encodeForm, success: formRes }; $("#loginform").ajaxForm( formSubOpt ); }); //提交成功 function formRes(responseText){ //參數名要爲這個 // console.log(responseText); ajaxAlerts(responseText); //提示 if(responseText.code<0){ changeVer(); $("input[name=ver]").val(""); } if(responseText && responseText.code==0){ setTimeout(function(){ location.href = "{$toURL}"; },750); } } //RSA加密帳號密碼 var RSApubKey = "{$RSApubKey}"; //console.log(RSApubKey); function encodeForm(formData){ // console.log(formData); //這是要提交的參數 var crypt = new JSEncrypt(); crypt.setKey( RSApubKey ); var USER = crypt.encrypt( $("input[name=name]").val() ); var PW = crypt.encrypt( $("input[name=psw]").val() ); // console.log( PW ); formData[0].value = USER; formData[1].value = PW; }
略。按前面的分析思路來寫便可