博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java获取访问者Ip并限制Ip访问页面
阅读量:4155 次
发布时间:2019-05-25

本文共 6185 字,大约阅读时间需要 20 分钟。

原文链接:

最近遇到一个需求,一个只能内网访问的网站,需要限制ip访问。就是网站内的部分文章只有白名单内的ip才能打开。因为是静态化的网站,所有文章都是静态html页面。所以首先想到的就是直接js获取访问者ip然后再判断是否在白名单内,不在白名单内就到没有权限页面。

但是JS获取内网Ip还是比较麻烦的,查到几个方法最后试了都不行。

记录下查到的几个方法和最后实现的方法。

JS获取外网ip的方法:

//最简单的获取外网ip的方法。可以直接用,但是没啥用..

JS获取内网Ip的方法://有些浏览器获取到的加密ip段有问题,所以当其时期

function getIP(callback) {        let recode = {};        let RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;        // 如果不存在则使用一个iframe绕过        if (!RTCPeerConnection) {            // 因为这里用到了iframe,所以在调用这个方法的script上必须有一个iframe标签            // 
            let win = iframe.contentWindow;            RTCPeerConnection = win.RTCPeerConnection || win.mozRTCPeerConnection || win.webkitRTCPeerConnection;        }        //创建实例,生成连接        let pc = new RTCPeerConnection();        // 匹配字符串中符合ip地址的字段        function handleCandidate(candidate) { debugger;            let ip_regexp = /([0-9]{1,3}(\.[0-9]{1,3}){3}|([a-f0-9]{1,4}((:[a-f0-9]{1,4}){7}|:+[a-f0-9]{1,4}){6}))/;            let ip_isMatch = candidate.match(ip_regexp)[1];            if (!recode[ip_isMatch]) {                callback(ip_isMatch);                recode[ip_isMatch] = true;            }        }        //监听icecandidate事件        pc.onicecandidate = (ice) => {            if (ice.candidate) {                handleCandidate(ice.candidate.candidate);            }        };        //建立一个伪数据的通道        pc.createDataChannel('');        pc.createOffer((res) => {            pc.setLocalDescription(res);        }, () => {});        //延迟,让一切都能完成        setTimeout(() => {            let lines = pc.localDescription.sdp.split('\n');            lines.forEach(item => {                if (item.indexOf('a=candidate:') === 0) {                    handleCandidate(item);                }            })        }, 1000);    }getIP(function (ip) { alert(ip); });

利用WebRTC获取真实内网Ip,WebRTC是一个支持网页浏览器进行实时语音对话或视频对话的API

由于WebRTC在建立连接过程中,会向对方发送本地地址SDP,因此可以通过访问SDP获得访问者的IP

但是有些浏览器用不了,所以还是放弃这种方式了。

 

 

最后还是觉得用Java来实现比较好吧,前端文章页写个ajax,每次进入文章先判断文章是否需要限制IP访问,如果需要就请求下后端,后端获取Ip判断是否在白名单内。注意ajax要用同步。

Java获取访问者Ip方法:

 String ip = request.getHeader("x-forwarded-for");        if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) {            ip = request.getHeader("Proxy-Client-IP");        }        if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) {            ip = request.getHeader("WL-Proxy-Client-IP");        }        if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) {            ip = request.getRemoteAddr();        }        System.out.println(ip);

完整代码

    
/**     * 判断文章是否有权可看     *      * @param map     * @return     */    @RequestMapping("/isIntranet.do")    @ResponseBody    public String isIntranet(ServletRequest request, ServletResponse response) {        Map
 map = new HashMap
();        HttpServletRequest req = (HttpServletRequest)request;        HttpServletResponse resp = (HttpServletResponse)response;        // 判断访问者Ip是否白名单内        boolean flag = isIPOK(req, resp);        System.out.println(flag);        if (flag) {            return "true";        } else {            return "false";        }    }    private boolean isIPOK(HttpServletRequest request, HttpServletResponse response) {        // String accessIP = IPUtil.getUserIp(request);        String ip = request.getHeader("x-forwarded-for");        if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) {            ip = request.getHeader("Proxy-Client-IP");        }        if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) {            ip = request.getHeader("WL-Proxy-Client-IP");        }        if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) {            ip = request.getRemoteAddr();        }        System.out.println(ip);        return isLAN(ip);    }    // 是否为内网网段    public boolean isLAN(String ip) {        if ("127.0.0.1".equals(ip)) {            return true;        }        boolean result = true;        try {            Properties prop = new Properties();            //获取设置Ip段的配置文件            InputStream in = this.getClass().getClassLoader().getResourceAsStream("ipConfig.properties");            prop.load(in);            // 遍历取值            Set
 objects = prop.keySet();            for (Object object : objects) {                String ipNot = new String(prop.getProperty((String)object).getBytes("iso-8859-1"), "gbk");                System.out.println(ipNot);                /*result = ipIsValid("192.168.8.78-192.168.255.255", ip) || ipIsValid("172.16.0.0-172.31.255.255", ip)                    || ipIsValid("10.0.0.0-10.255.255.255", ip);*/                result = ipIsValid(ipNot, ip);            }            in.close();        } catch (IOException e) {            e.printStackTrace();        }        return result;    }        //校验Ip是否包含在Ip段内    public static boolean ipIsValid(String ipSection, String ip) {        if (ipSection == null) {            throw new NullPointerException("IP段不能为空!");        }        if (ip == null) {            throw new NullPointerException("IP不能为空!");        }        ipSection = ipSection.trim();        ip = ip.trim();        final String REGX_IP =            "((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";        final String REGX_IPB = REGX_IP + "\\-" + REGX_IP;        if (!ipSection.matches(REGX_IPB) || !ip.matches(REGX_IP)) {            return false;        }        int idx = ipSection.indexOf('-');        idx = idx < 0 ? ipSection.length() : idx;        String[] sips = ipSection.substring(0, idx).split("\\.");        String[] sipe = ipSection.substring(idx + 1).split("\\.");        String[] sipt = ip.split("\\.");        long ips = 0L, ipe = 0L, ipt = 0L;        for (int i = 0; i < 4; ++i) {            ips = ips << 8 | Integer.parseInt(sips[i]);            ipe = ipe << 8 | Integer.parseInt(sipe[i]);            ipt = ipt << 8 | Integer.parseInt(sipt[i]);        }        if (ips > ipe) {            long t = ips;            ips = ipe;            ipe = t;        }        return ips <= ipt && ipt <= ipe;    }

以上方法均来自网络,亲测有效,记录于此。

I am just a porter

转载地址:http://omwxi.baihongyu.com/

你可能感兴趣的文章
makefile中“-“符号的使用
查看>>
go语言如何从终端逐行读取数据?------用bufio包
查看>>
go的值类型和引用类型------重要的概念
查看>>
求二叉树中结点的最大值(所有结点的值都是正整数)
查看>>
用go的flag包来解析命令行参数
查看>>
来玩下go的http get
查看>>
队列和栈的本质区别
查看>>
matlab中inline的用法
查看>>
如何用matlab求函数的最值?
查看>>
Git从入门到放弃
查看>>
java8采用stream对集合的常用操作
查看>>
EasySwift/YXJOnePixelLine 极其方便的画出真正的一个像素的线
查看>>
Ubuntu系统上安装Nginx服务器的简单方法
查看>>
Ubuntu Linux系统下apt-get命令详解
查看>>
ubuntu 16.04 下重置 MySQL 5.7 的密码(忘记密码)
查看>>
Ubuntu Navicat for MySQL安装以及破解方案
查看>>
HTTPS那些事 用java实现HTTPS工作原理
查看>>
oracle函数trunc的使用
查看>>
MySQL 存储过程或者函数中传参数实现where id in(1,2,3,...)IN条件拼接
查看>>
java反编译
查看>>