バックエンドインタフェースへのアクセスを制限


シナリオ:携帯電話の認証コードやメールボックスの認証コードを送信する際の制限ルール:1分に1回しか送信できず、1日に回数制限もあります.悪意のあるアクセスを防止し、サーバの圧力を低減します.
解決策:ユーザipアドレスを取得し、このipが初めてアクセスするかどうかを判断し、初めてアクセスする場合はredisでminKey,dayKeyを作成する.minKeyが60 s期限切れになり、dayKeyが86400 s、つまり24 Hになるように設定します.初回アクセスは1回加算されます.1回または1日が制限回数を超えた場合は、アクセスを禁止します.
1.ユーザの実際のipアドレスを取得する.
 
/**
 *           
 *      IP      
 */
public class GetIpAddressUtil {
    /**
     *       IP  ,   request.getRemoteAddr();                      IP  ,
     * 
     *   ,             ,X-Forwarded-For       ,    IP ,               IP ?
     *     X-Forwarded-For     unknown   IP   。
     * 
     *  :X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
     * 192.168.1.100
     *     IP : 192.168.1.110
     * @param request
     * @return
     */
    public static String getIpInfo(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }
}

 
2.Redis構成
ublic class MyJedisPool {
    private final static Logger logger = LoggerFactory.getLogger(MyJedisPool.class);
    private static JedisPool jedisPool = null;
    //redis    
      public static final String Redis_IP = "192.168.xx.xx";
      public static final int Redis_PORT =6379;
      public static final String Redis_jedisUser ="";//  
      public static final int ExpireSeconds = 3600;
    //          
    static {
        try{
            //  jedis     
            JedisPoolConfig config = new JedisPoolConfig();
            //       
            config.setMaxTotal(20);
            config.setMaxIdle(10);
            config.setMaxWaitMillis(3000);
            config.setTestOnBorrow(true);
            config.setTestOnReturn(false);
            //       jedis 
            //jedisPool = new JedisPool(config,Redis_IP,Redis_PORT,1000*2,Redis_jedisUser);
            jedisPool = new JedisPool(config,SystemFileConfig.get("Redis_IP"),
                    Integer.parseInt(SystemFileConfig.get("Redis_PORT")),
                    1000*2,
                    SystemFileConfig.get("Redis_jedisUser"),
                    Integer.parseInt(SystemFileConfig.get("Redis_database")));     
        }catch (Exception e) {
            logger.info("redis     ",e);
        }
    } 
    /**  jedis  */
    public static Jedis getJedisObject(){
        return jedisPool.getResource();
    }
    
    /**  jedis  */
    public static void returnJedisOjbect(Jedis jedis){
        if (jedis != null) {
            jedis.close();
        }
    }
}

 
3.操作redis完了回数制限
String userIpAddr = GetIpAddressUtil.getIpInfo(request);
Jedis jedis = MyJedisPool.getJedisObject();//  jedis    
boolean flag = true;               
flag = limitSendCount(userIpAddr,jedis);
System.out.println(flag); //  flag        
if (jedis != null) {
    jedis.close();  //    jedis  
}                        
//        
 public boolean limitSendCount(String ip, Jedis jedis) {     
            String value = jedis.get(ip+"MinLimte");
            String dayValue = jedis.get(ip+"DayLimte");
            if(value==null){
                jedis.set(ip+"MinLimte", "1");
                jedis.expire(ip+"MinLimte", 60);//      60 
                if(dayValue==null) {
                    jedis.set(ip+"DayLimte", "1");
                    jedis.expire(ip+"DayLimte", 86400);//      24hours
                }else {
                    jedis.incr(ip+"DayLimte");  //   
                    int parseIntDay = Integer.parseInt(dayValue);
                    if(parseIntDay>20){
                        System.out.println("    !!!!");
                        return false;
                    }
                }
                return true;
            }else{
                int parseInt = Integer.parseInt(value);
                int parseIntDay = Integer.parseInt(dayValue);
                60      1 ,      20 ,     
                if(parseInt>=1 || parseIntDay>20){
                    System.out.println("    !!!!");
                    return false;
                }
                jedis.incr(ip+"MinLimte");
                jedis.incr(ip+"DayLimte");
            }            
            return true;
        } 

4.バックエンドの検証が完了しました.前後が分離されていない場合、フロントエンドはボタンをクリックした後にクリックを禁止する必要があり、ボタン表示カウントダウンが0 sになるまで再度クリックできる場合、フロントエンドjsは以下の通りである.
//     60        
var id = 60;
//    
var timeing = setInterval(function() {
    id = id - 1;
    $('#sendVcode').html(id + 's');
    }, 1000);
//    
window.setTimeout(function() {
   //    ,      
   clearInterval(timeing);
   $('#sendVcode').html('    Send').removeAttr("disabled");
   $("#sendVcode").removeClass("sendclass2");//         
   $("#sendVcode").addClass("sendclass1");
}, 60000); 

参照リンク:https://www.cnblogs.com/lhc-hhh/p/13176505.html