我知道是http是无状态的,但可以通过服务端生成sessionId然后通过Set-Cookie响应头发送给客户端,然后浏览器会自动带上cookie。我想实现的功能是:限制客户端访问频率,比如限制同一个客户端一秒内只能访问两次。如果是用户登录状态下就简单了,通过cookie或token就可以判断唯一的用户然后限制访问频率。但是不登录的情况下怎么办呢,不想做成知乎那样不登录就不让访问然后跳往登录页面。能想到的User-Agent头肯定不行,获取客户端ip也行不通吧。是不是只有上面那种服务端生产session然后Set-Cookie的方式才能解决了?
那遇到不支持cookie的客户端是不是也无能为力了。对于生成token,然后客户端带上这个token,那都是客户端和服务端提前适配好的吧?对于一个不知道什么的客户端,是不会带上服务器返回的token的对吧。那对于不支持cookie的随便一个什么未知的客户端,是不是就做不到限制其访问频率了?
你的想法非常好 先阶段没有什么方法是绝对安全 只能采取一些措施来保证相对安全的http访问 我提供几个想法 你可以参考下
1.使用IP地址限制:可以根据客户端的IP地址来限制访问频率,但是这种方法容易受到IP伪造等攻击,而且如果多个用户共用同一IP,就会出现误判的情况。
2.动态口令:可以在服务端生成一个动态口令,然后将其返回给客户端,客户端每次请求时需要带上该口令,服务端验证通过后才能继续访问。不过这种方法需要客户端和服务端都支持动态口令验证。
3.验证码:可以在客户端请求时弹出验证码,需要用户输入正确的验证码才能继续访问。不过这种方法可能会影响用户体验。
获取ip:
public String getIpAddress(HttpServletRequest request) {
String ip = null;
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
ip = request.getHeader("x-forwarded-for");
}
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("entrust-client-ip");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip.trim())){
InetAddress inetAddress = null;
try{
inetAddress = InetAddress.getLocalHost();
}catch (UnknownHostException e){
System.out.println("获取IP地址失败");
}
ip = inetAddress.getHostAddress();
}
}
//多级 方向代理
if (ip.indexOf(",")>0){
ip = ip.substring(0,ip.indexOf(",")).trim();
}
return ip;
}