controller層實現如下,其中,const是乙個新建的狀態類,儲存各類常量值,包括當前登入使用者的字串名稱,並將它會作為鍵值儲存在session域中。
}這是service層的實現**,首先接收到controller層傳遞過來的使用者名稱和密碼,在資料庫中校驗使用者名稱,然後對密碼進行md5加密,將加密後的資料拿到資料庫中校驗,校驗通過,返回給前端使用者名稱和成功訊息。
@autowired
@override
public serverresponselogin(string username, string password)
//md5密碼驗證
string md5password = md5util.md5encodeutf8(password);
if(user==null)
user.setpassword(stringutils.empty);
return serverresponse.createbysuccess("登入成功",user);
}
md5加密演算法如下,其中加入了鹽值增加了破解難度:
/**
* 返回大寫md5
**@param origin
*@param charsetname
*@return
*/private
static string md5encode(string origin, string charsetname) catch (exception exception)
return resultstring.touppercase();
}public
static string md5encodeutf8(string origin)
註冊功能用到乙個新定義的const類,這是乙個通用狀態類,使用了靜態常量、列舉、介面三種定義方式,以後會常常用到,註冊需要填寫使用者名稱和郵箱,兩種都要判斷是否已存在的問題,同時對密碼加密處理。
public serverresponseregister(user user)
validresponse = checkvalid(user.getemail(), const.email);
if(!validresponse.issuccess())
user.setrole(const.role.role_customer);
//md5加密
user.setpassword(md5util.md5encodeutf8(user.getpassword()));
if(resultcount==0)
return serverresponse.createbysuccessmessage("註冊成功");
}/**
* 校驗是否存在,供註冊方法復用
*@param str
*@param type
*@return
*/public serverresponsecheckvalid(string str,string type)
}if(const.email.equals(type))
}}else
return serverresponse.createbysuccess();
}
重置密碼功能與密保問題的設定相關,首先是選擇問題,從當前登入使用者中選擇註冊時設定的問題,用google瓜娃stringutils判斷是否為空。
public serverresponse selectquestion(string username)
if(stringutils.isnotblank(question))else
}
驗證答案是否正確,這裡用到了加token的做法,主要是為了防止產生橫向越權的問題,token使用uuid(全球統一標識碼),儲存在瓜娃提供的快取中,並且設定過期時間(12小時)
//lru(least recently used,最近最少使用)快取淘汰演算法
private
static loadingcachelocalcache= cachebuilder.newbuilder().initialcapacity(1000).maximumsize(10000).expireafteraccess(12, timeunit.hours)
.build(new cacheloader()
});
要過期時間的原因是,這次修改需要保證在一段時間內有效,過期就無效了。因為token也可以被攔截~~ 再進一步的做法是使用token修改完之後,把token置成失效。結合「忘記密碼重置密碼」(即forget_reset_password.do)這個介面一起看,例如不加token,那麼通過修改密碼的介面 就可以隨便改其他username的密碼了。如果加token,加了有效時間,起碼在一段時間內,我保證自己的修改是有效且防止其他無效。
這在網際網路上修改密碼是乙個很常用的做法,例如,忘記密碼修改郵件裡面給的鏈結,都會有乙個提示,告訴你,這個修改密碼的鏈結在10個小時之內有效,過期請重新獲取該鏈結~
public serverresponse<
string
> checkanswer(string username,string question,string answer)
return serverresponse.createbyerrormessage("答案錯誤");
}//必須答對密保問題才可以重置密碼
public serverresponse<
string
> forgetresetpassword(string username,string passwordnew,
string forgettoken)
serverresponse<
string
> response = checkvalid(username, const.username);
if(response.issuccess())
string token = tokencache.getkey(const.token_prefix + username);
if(stringutils.isblank(token))
if(stringutils.
equals(forgettoken,token))else
}else
}
//防止橫向越權 一定要驗證舊密碼 確定是指定使用者 也要附加id進行密碼查詢 因為密碼有重複 count(1)結果可能大於1 結果就是true了
// 第一步驗證使用者身份,這時提交第乙個請求報文,驗證成功之後,進入第二步;
// 第二步才是真正的修改密碼的動作,而修改密碼的post資料報有3個請求引數,分別是新密碼、確認新密碼以及賬號值。
// 問題就出在第二步,在執行修改密碼的動作時,伺服器並未驗證被修改密碼的賬戶是否是第一步中通過身份驗證的賬戶,
// 因此攻擊者可以很容易的以自己的身份通過認證,然後修改第二步提交的報文,實現對任意賬戶的密碼修改!
public serverresponseresetpassword(string passwordold,string passwordnew,user user)
user.setpassword(md5util.md5encodeutf8(passwordnew));
if(resultcount>0)
return serverresponse.createbyerrormessage("密碼更新失敗");
}
同樣也必須注意越權問題,使用者名稱和email同時檢查.
public serverresponseupdateinfomation(user user)
user update_user=new user();
update_user.setphone(user.getphone());
update_user.setquestion(user.getquestion());
update_user.setanswer(user.getanswer());
update_user.setemail(user.getemail());
update_user.setid(user.getid());
if(countresult>0)
return serverresponse.createbyerrormessage("修改失敗");
}
在contoller實現如下:
const賬戶中取出當前使用者即可。
2020 7 24 使用者管理模組
今天記錄的主要關於sql的幾個新接觸的用法 第一種 select top 1 exist from table 該行語句可翻譯為 查詢表table中存在的資料的第一行 該語句的目的是 判斷表table中是否存在資料 因為有 exist 因此我們在返回的結果中可以看到字段 exist 同理,由此衍生的...
mysql 使用者管理 pymysql模組
mysql使用者管理 mysql是乙個tcp伺服器用於操作伺服器上的檔案資料 在mysql自帶的mysql資料庫中有4個表用於使用者管理的 分別是 優先順序從高到低 user db tables priv columns priv 1.建立使用者的語句 create user 使用者名稱 主機位址 ...
許可權管理 使用者與模組關係
使用者與模組關係功能,您可以寫成跟使用者與角色關係一樣。不過下面實現方法會看到更多的許可權控制。介面如下截圖 資料表結構如下 setansi nulls ongo setquoted identifier ongo create table dbo usersmodule usersid int n...