美好的明天

分享改变,记录生活
美好的明天
当前位置: 首页 > WordPress > 正文

前言

前段时间开始,抖音、微信公众号、微博等平台的评论区都开始显示用户的IP归属地了。于是,我就想到了能不能将这个功能在博客的评论区也实现,折腾了一下,发现是可以做到的,这里记录一下。

提示

因腾讯、高德等各家IP定位API均有次数限制,超出限制则要付费,价格还不低,若您的网站流量较大则可能涉及到付费才能使用,若你和我一样囊中羞涩,则可使用本站搜集的另一种方法 WordPress使用纯真IP库实现评论显示IP归属地方法(IPv4) - 美好的明天 (wmviv.com) ,除不支持解析IPv6协议用户提交的评论其他还是都能搞定的,优点是本地化不依赖,二者流程不一,但实际效果均简单粗暴,区别仅差别于对IPv6的支持,请按需自取;

获取用户IP

第一个要解决的问题就是获取用户的 IP 地址,我使用的是 WordPress 搭建的博客,可以直接使用get_comment_author_ip()即可获取到用户的 IP 地址。

基于IP识别归属地

第二步就是需要基于获取的 IP 地址去识别 IP 的归属地了,可直接使用的”腾讯位置服务“的 API 接口,每日有 10000 次免费查询额度,对于我这个小站来说足够了。
首先打开腾讯位置服务,注册及登录账号,进入到控制台,找到【应用管理】--> 【我的应用】;
然后点击创建新的应用,名称和类型随便填写,应用创建好后,点击【添加】--> 选择 “Web服务” ,名称可以随便写,勾选“阅读并同意协议”--> 点击【提交】,然后再回到【我的应用】界面,即可看到一个 "key",将 "key" 复制并保存好,后面需要用到。

构建代码

在站点根目录下新建一个get_user_address.php文件,然后写入以下代码。

粘贴上面得到的Key替换掉【腾讯位置服务API】

<?php
function province($user_ip) {
    if (filter_var($user_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_IPV4)) {
        if (filter_var($user_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
            $url = "https://apis.map.qq.com/ws/location/v1/ip?key=【腾讯位置服务API】&ip=" . $user_ip;
            $UserAgent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022; .NET CLR 1.0.3705; .NET CLR 1.1.4322)';
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($curl, CURLOPT_ENCODING, '');
            curl_setopt($curl, CURLOPT_USERAGENT, $UserAgent);
            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
            $data = curl_exec($curl);
            $data = json_decode($data, true);
            $result = array_column($data, 'ad_info');
            $nation = array_column($result, 'nation'); // 获取国家
            $nation = array_shift($nation); // 获取国家
            $province = array_column($result, 'province'); // 获取省份
            $province = array_shift($province); // 获取省份
            $ad_info = $nation == "中国" ? $province : $nation; // 判断,如果国家为中国,则显示省,否则显示国家
            $ad_info = isset($ad_info) ? $ad_info : "未知";
            return $ad_info;
        } else {
            return "私网用户";
        }
    } else {
        return "未知";
    }
}
?>

代码引用

在主题根目录下找到functions.php文件,最后一行加入如下代码:

// 评论区添加显示用户IP归属地 www.wmviv.com
include("get_user_address.php");

如果不想每次更新主题后都重新修改代码,可以将该代码放入到子主题的functions.php文件中。我使用的果核开发的 CorePress Pro 主题 这个主题是支持子主题的,如果你使用的主题不支持,也可使用Code Snippets插件,这样可以避免升级主题后又要重新改一遍代码。

评论区显示

怎么在评论区显示呢?直接找到主题的评论的那个文件,我这里的文件路径是geekframe/comment-pro.php,在显示评论时间的代码后面加入如下代码即可,CorePress Pro 主题大概在第 46 行,放到后面,主题更新后记得加代码,其他主题的话根据主题的具体情况操作吧。

 ·<a style="color: #07c160;"><!--?php echo province(get_comment_author_ip()); ?--></a>

效果演示

大家可以在评论区留言测试

遇到的小问题

CDN获取不了真实IP

我的博客使用的 CDN 进行加速,获取到的用户的IP地址是 CDN 节点的地址,这样就造成了获取的地址没有实际的作用,那么这里就需要修改一个 WordPress 程序的代码,让其可以获取到真实的 IP 地址。
找到站点目录下的 wp-config.php 文件,在文件内的 <?php 标记后加入如下代码:

if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$list = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $list[0];
}这样就可以获取到用户真实的IP地址了。

IPv6 用户访问留言不显示归属地

因为我的网站是同时支持 IPv4 和 IPv6 访问的,那么基于 IPv6 访问的用户留言归属地无法识别出来。这个问题的出现是由于我原先使用的是高德的 IP 查询归属地 API 服务,因为高德的 API 是不支持 IPv6 的,所以出现了这个问题,那么解决方案就是找一个支持 IPv6 解析的 API 就可以了。找了一圈,发现大部分支持 IPv6 解析的都是收费的而且价格特别的高,同时也折腾了一下使用纯真和 GeoIP 解析,但是效果都不太理想,主要是解析的不准确还有部分 IP 地址识别不出来。最后发现腾讯位置服务提供的 API 解析是支持 IPv6 的,且有一定的免费额度(个人认证:10000次/天)可以满足小网站的需求,于是解析 API 归属地的接口就换成了腾讯的 API 了。

访问的用户修改 XFF 头部 IP 地址后,识别出来的的地址不显示;

这个问题无法避免,没办法限制用户修改 XFF,所以解决方案就只能是:

如果用户修改后的地址是正常 IP 地址,就直接解析就行了,只是解析出来的结果不一定准确,这个没办法;
如果用户修改后的地址非正常 IP 地址,比如是:私网地址、环回地址等,那就直接解析成”私网用户“标记就可以了;
如果用户修改后,没有地址了,那就直接显示”未知IP“了。

国外用户访问不显示归属地

因为我的网站禁用了国外用户访问,一开始没有发现这个问题,后来在群友的网站上发现了。这个问题的原因是由于直接提取的解析结果中的省份,但是大部分国外 IP 无法判断出来省份,所以省份内容为空了,造成了不显示。这里的解决办法就是同时提取国家和省份,如果发现国家是”中国“那么直接显示省份,如果发现国家不是”中国“,那就直接显示国家就可以了。

没有获取用户的IP地址,不显示内容。

这个问题是由于部分用户通过特殊手段隐藏了 IP 地址,导致获取不到 IP 地址信息。获取不到地址信息会造成代码报错,导致整个页面都无法访问了,所以解决办法就是加一个判断,没有获取地址就直接显示”未知IP“。

最后

可能还有其他的问题,后续发现了再慢慢改进吧,也欢迎在评论区测试留言。

代码参考:评论区显示用户IP归属地 - 广然笔记 (rsecc.cn)

温馨提示
本页面最后更新于:2022-09-20 23:10:53,距今已 952 天,若有链接失效或教程无效,欢迎留言反馈。
THE END

目前有 2 条评论

  1. 2333
    板凳
    2333

    试试

  2. 海誓不盟
    沙发
    海誓不盟

    学习一下 顺便看看我在哪 [f=wozuimei]

发表评论

gravatar

OK aixin aoman baoquan bizui cahan caidao ciya dabing doge fadai ganga guzhang haixiu hanxiao huaixiao jie jingkong keai koubi ku leiben lenghan liuhan nanguo penxue piezui qiang qinqin quantou se shengli shuai tiaopi touxiao tuosai weiqu woshou wozuimei wunai xiaojiujie xiaoku xieyanxiao xigua yinxian yiwen youling yun