评论区显示用户IP归属地

前言

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

具体操作

获取用户IP

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

基于IP识别归属地

第二步就是需要基于获取的 IP 地址去识别 IP 的归属地了,我直接使用的”高德开发平台“的 API 接口,每日有 5000 次免费查询额度,对于我这个小站来说足够了。

首先打开高德开发平台,注册一个账号,进入到控制台,找到【应用管理】--> 【我的应用】;

然后点击创建新的应用,名称和类型随便填写,应用创建好后,点击【添加】--> 选择 “Web服务” ,名称可以随便写,勾选“阅读并同意协议”--> 点击【提交】,然后再回到【我的应用】界面,即可看到一个 "key",将 "key" 复制并保存好,后面需要用到。

构建代码

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

高德和百度的API都有,不用的那个可以删除或者注释掉。

<?php
function province($user_ip)
{
        if(!filter_var($user_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
        {
         //高德API
        $url = "https://restapi.amap.com/v3/ip?key=【替换为高德控制台获取的key】&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);
        $province = isset($data['province']) ? $data['province'] : "未知"; 
        return $province;
           //百度API
        // $url = "https://api.map.baidu.com/location/ip?ak=【替换为百度控制台获取的ak】&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, 'address_detail');
        // $resulta = array_column($result, 'province');
        // $province = array_shift($resulta);
        // return $province;
        }
        else
        {
        $province = "因为穷,IPv6访客暂不支持显示归属地";
        return $province;
        }
}
?>

代码引用

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

include("get_user_address.php");

如果不想每次更新主题后都重新修改代码,可以将该代码放入到子主题的 functions.php 文件中。我用的果核开发的 CorePress Pro 主题 这个主题是支持子主题的,如果你使用的主题不支持,当我没说。

评论区显示

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

·<a style='color:#07C160'><?php echo province(get_comment_author_ip()); ?></a>

效果演示

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

image-20220817210254925

遇到的小问题

我的博客使用的 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访问的暂时不支持显示归属地,因为高德的API暂时不支持IPv6,百度的API支持IPv6但目前仅面向企业认证的开发者使用,其他的API收费有点承受不起,下图是我能找到的最便宜的了,如果有更好的欢迎大家推荐。

评论区留言试试看吧!

峰回路转

最后发现,腾讯位置服务支持 IPv6 查询归属地,所以我现在已经切换成了腾讯的API,腾讯的调用和百度类似,就不改代码了,自己琢磨一下吧。
后续的修改可以看这里:
https://www.rsecc.cn/760.html


THE END