Redis限制一鍵登錄次數

一、產生背景

之前的隨筆提到過項目中寫了一鍵登錄功能、上線後除了有時候網路波動會導致登陸失敗,其他情況一直穩如老狗

image

しかし,郵件看到有人惡意刷一鍵登錄,這年頭閑的人可真閑啊,
只能思考如何搞一搞

image

二、解決思路

因為項目實現一鍵登錄採用的是 自有伺服器調用 所以限制一鍵登錄分為兩步走,因為每個手機號有唯一的openid所以拿openid做redis的key值

(1)、調用雲函數之前

調用雲函數之前,前端會發起請求給後台,拿到這個請求後去 Redis 中檢查2小時的登錄次數如果大於設定閾值就返回限制一鍵登錄次數,否則就放行通過

(2)、調用雲函數

調用時使用Redis的 setNX()(命令在指定的 key 不存在時,為 key 設置指定的值,這種情況下等同 SET 命令。當 key存在時,什麼也不做。)因為第一次不存在key所以設置一個初始值和過期時間。接下來使用Redis的 incrBy() 使value自增,每次調用value就+1。

三、上手編碼

(1)、調用雲函數前編碼

public static void checkOneLogin(String openid) {
        if (StringUtils.isBlank(openid)) {
            "參數校驗,拋出自定義異常即可";
        }
        //從Redis獲取該用戶半小時內登錄次數
        String s = RedisHelper.get(RedisHelper.get(openid));
        //如果為空直接返回
        if (StringUtils.isBlank(s)){
            return;
        }
        //如果redis存儲OpenId並且 value大於10拋出異常
        if (Integer.parseInt(s) >= 10) {
            log.info("[日誌]用戶{}在{}因一鍵登錄次數過多,被暫時禁止一鍵登錄",openid,new Date());
            "記錄日誌,拋出異常";
        }
    }

(2)、調用雲函數編碼

public static void oneLoginOK(String openid) {
        //首次進入賦予默認值
        boolean nx = RedisHelper.setNx(RedisHelper.get(openid), "1", 60 * 30);
        //首次進入返回
        if (nx) {
            return;
        }
        //登錄成功自增1
        Long incr = RedisHelper.incrBy(RedisHelper.get(openid));
        if (incr >= 10) {
            //設置過期時間
            RedisHelper.expire(RedisHelper.get(openid), 60 * 60 * 2);
        }
    }

寫的不是很規範,實際開發要加Redis頭等 總的來說遇到的問題也不老少,還有雲函數記憶體不夠的情況、、網路稍有問題也會出現問題~~~

image