最近的nuxt业务有个需求是为了防止非法爬虫爬取数据,需要对用户ip做一个判断,如果是非法爬虫就返回一个空白页面。
判断用户ip这个过程是通过接口去判断的,本地开发获取用户ip正常,上到测试环境后,查看请求的日志就发现问题了。(关于nuxt如何做日志打点,可以看这片文章:使用nuxt-winson-log打印nuxt日志与日志分级)
通过日志发现,使用req.socket.remoteAddress || req.connection.socket.remoteAddress;
发现获取到的ip是127.0.0.1
,推测是多了一层 nginx 的转发,导致用户真实ip获取不到。搜索了一下发现很多人也有这个问题。解决的方法也很简单,在nginx的配置里增加一个配置即可:
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Real-IP $client_ip;
proxy_set_header X-Client-Source-IP $remote_addr;
}
原理是请求通过nginx转发到http://localhost:3000后,在请求头加上X-Real-IP
和X-Client-Source-IP
两个请求头,请求头的内容是$client_ip
和$remote_addr
。运维大佬叫我优先拿X-Client-Source-IP
,最后再拿X-Real-IP
,因为``X-Real-IP```有可能拿到代理机的ip。配置完成后像下面这样获取用户ip即可:
// nginx中请求头的大写都改成小写
const ip =
req.headers['x-client-source-ip'] ||
req.headers['x-real-ip'] ||
req.connection.remoteAddress;
nuxt 如何获取用户ip并做处理
使用nuxt的middleware
机制,写一个中间件,配置到nuxt.config.js
的router
里,这样每次访问页面的时候都会触发编写的中间件。
/middleware/checkip.js
export default async ({ req, error, $winstonLog }) => {
if (process.server) {
// x-real-ip 通过nginx配置添加
const ip =
req.headers['bigo-x-client-source-ip'] ||
req.headers['x-real-ip'] ||
req.connection.remoteAddress;
// 对ip做业务处理
}
return true;
};
/nuxt.config.js
export default {
router: {
middleware: 'checkIp'
}
}
中间件有个令人疑惑的地方是,根据我的日志显示,这个中间件每访问一次路由会触发两次😢,难道是触发了两次路由吗。希望有知道的大佬可以解答这个疑惑~
配置 nginx 时应该注意的问题
配置 nginx 的过程中犯了一个错误是,修改完后直接重启了。请教了后台大佬,看他一顿操作后执行了一个步骤:
sudo /usr/local/nginx/sbin/nginx -t -c /data/services/nginx-1.14.2.3/conf/nginx.conf
不懂就问,问大佬这个操作是什么意思,大佬说这是检查 nginx 的配置后做一遍检查。 如果修改配置后马上重启,如果配置出错,会导致 nginx 无法正常重启,这样会导致 nginx 挂掉,机器上所有需要经过 nginx 转发的业务也会无法转发!
所以配置完 nginx 后的步骤应该是保存后检查配置,无问题后再重启 nginx:
检查:
sudo /usr/local/nginx/sbin/nginx -t -c /data/services/nginx-1.14.2.3/conf/nginx.conf
重启:
sudo /usr/local/nginx/sbin/nginx -s reload
当然每台机器安装的 nginx 版本和位置可能会有不同。但命令是一样的。
直接操作机器真的是需要谨慎,稍有不慎可能就会导致机器上的进程挂掉。
参考 文章:
Node.js 获取用户真实IP - 简书
网友评论