JFinal

登录 注册

开放接口IP访问控制拦截器

基本思路:配合Redis使用。

拦截器代码:

package ....interceptor;

import java.util.Objects;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;


/**
* @author 作者:qiww
* @createDate 创建时间:2018年6月11日 下午5:01:36
* 
* 对于开放接口进行IP访问控制<br>
* 
* 开发接口是指无需token验证的接口。
*/
public class IPControlInterceptor implements Interceptor {
	static Cache cache = Redis.use("...");

	@Override
	public void intercept(Invocation inv) {
		if (isLimitedIP(inv)) {
			((BaseController) inv.getController()).renderAppError("IP已被锁定,请稍后重试");
			return;
		}
		
		inv.invoke();
	}
	
	/**
	 * @param inv
	 * @return false-无限制IP,true-已限制IP
	 */
	public static boolean isLimitedIP(Invocation inv) {
		try {
			//测试环境无限制
			boolean testmode = PropKit.getBoolean("testMode", true);
			if (testmode) {//测试环境无IP限制
				return false;
			}
			
			//获取IP地址
			String IP = StringUtil.getIP(inv.getController().getRequest());
			
			//本地测试
			if (Objects.equals("127.0.0.1", IP)) {
				return false;
			}
			
			//判断IP是否已经被锁定
			if (cache.exists("openapi:lock:" + IP)) {
				//已经锁定
				return true;
			} 
			
			//若没有锁定,记录访问次数
			String keyCounts = "openapi:calltimes:" + IP;
			if (cache.get(keyCounts) != null) {
				Long times = cache.get(keyCounts);
				
				//是否达到最大访问次数:1*60秒内同一最大访问次数为100,锁定时间为1*60秒
				if (times+1 >= 100) {
					cache.del(keyCounts);
					cache.set("openapi:lock:" + IP, times);
					cache.expire("openapi:lock:" + IP, 1*60);
					return true;
				} else {
					cache.set(keyCounts, times+1);
					cache.expire(keyCounts, 1*60);
					return false;
				}
			}
			
			cache.set(keyCounts, 1L);
			
			return false;
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return false;
		}
		
	}

}


应用实例:

@Clear(TokenVerificationInterceptor.class) //公开接口
@Before(IPControlInterceptor.class) //IP访问限制
public void register() {//注册
	//TODO
	...
}


评论

  • 06-12 18:06
    使用 reids 的好处是可以持久化数据,以及有丰富的数据结构和 API 支持,但缺点是需要跑一个 server ,以及网络通信会有一定的延迟

    谢谢分享
  • 06-12 18:06
    这个设计可以很容易去推广到使用 ehcache
  • 发送