系統(tǒng)登錄的時(shí)候經(jīng)常會(huì)有這種場(chǎng)景,如果密碼連續(xù)N次輸入錯(cuò)誤,則要等N分鐘之后才能重試。實(shí)現(xiàn)的方式有多種缔刹,比如在內(nèi)存中維護(hù)一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)這些信息球涛,但實(shí)現(xiàn)起來(lái)比較麻煩而且也存在問(wèn)題,比如應(yīng)用重啟會(huì)導(dǎo)致數(shù)據(jù)丟失校镐,并且內(nèi)存的占用也是一個(gè)問(wèn)題亿扁。
如果項(xiàng)目中已經(jīng)有用到redis,那么使用redis來(lái)實(shí)現(xiàn)此功能是非常簡(jiǎn)單且有保障的鸟廓。利用redis的String數(shù)據(jù)結(jié)構(gòu)和超時(shí)自動(dòng)過(guò)期機(jī)制从祝,每錯(cuò)誤一次,則錯(cuò)誤值+1引谜,并設(shè)置相應(yīng)的過(guò)期時(shí)間牍陌,在登錄的時(shí)候判斷從key中獲取到失敗次數(shù)是否大于最大失敗次數(shù)即可。
/**
* 登錄次數(shù)錯(cuò)誤+1
*
* @param userName
*/
private void increaseFailedLoginCounter(String userName) {
String key = ERROR_COUNT_KEY + userName;
JedisCluster cluster = jedisClusterManager.getJedisCluster();
String v = cluster.get(key);
if (org.springframework.util.StringUtils.isEmpty(v)) {
cluster.set(key, "1");
} else {
cluster.incr(key);
}
cluster.expire(key, 1800);
}