nginx proxy_set_header设置、自定义header

 

先来看下proxy_set_header的语法
语法: proxy_set_header field value;
默认值:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
上下文: httpserverlocation

容许从新定义或者添加发日后端服务器的请求头。value能够包含文本、变量或者它们的组合。 当且仅当当前配置级别中没有定义proxy_set_header指令时,会从上面的级别继承配置。 默认状况下,只有两个请求头会被从新定义:html

 

proxy_set_header Host       $proxy_host;
proxy_set_header Connection close;
 
proxy_set_header也能够自定义参数,如:proxy_set_header test paroxy_test;

 

若是想要支持下划线的话,须要增长以下配置:java

underscores_in_headers on;
linux

 

能够加到http或者server中nginx

语法:underscores_in_headers on|off
默认值:off
使用字段:http, server
是否容许在header的字段中带下划线web


在java端,须要获取proxy_set_header的参数时,须要使用request.getHeader(field),通常用来获取真实ip地址后端

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------服务器

 

使用Nginx后如何在web应用中获取用户ip及原理解释


 

 

问题背景:post

在实际应用中,咱们可能须要获取用户的ip地址,好比作异地登录的判断,或者统计ip访问次数等,一般状况下咱们使用request.getRemoteAddr()就能够获取到客户端ip,可是当咱们使用了nginx做为反向代理后,使用request.getRemoteAddr()获取到的就一直是nginx服务器的ip的地址,那这时应该怎么办?ui

part1:解决方案spa

我在查阅资料时,有一本名叫《实战nginx》的书,做者张晏,这本书上有这么一段话“通过反向代理后,因为在客户端和web服务器之间增长了中间层,所以web服务器没法直接拿到客户端的ip,经过$remote_addr变量拿到的将是反向代理服务器的ip地址”。这句话的意思是说,当你使用了nginx反向服务器后,在web端使用request.getRemoteAddr()(本质上就是获取$remote_addr),取得的是nginx的地址,即$remote_addr变量中封装的是nginx的地址,固然是无法得到用户的真实ip的,可是,nginx是能够得到用户的真实ip的,也就是说nginx使用$remote_addr变量时得到的是用户的真实ip,若是咱们想要在web端得到用户的真实ip,就必须在nginx这里做一个赋值操做,以下:

proxy_set_header            X-real-ip $remote_addr;

其中这个X-real-ip是一个自定义的变量名,名字能够随意取,这样作完以后,用户的真实ip就被放在X-real-ip这个变量里了,而后,在web端能够这样获取:

request.getAttribute("X-real-ip")

这样就明白了吧。

 

part2:原理介绍

这里咱们将nginx里的相关变量解释一下,一般咱们会看到有这样一些配置

server {

        listen       88;

        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location /{

            root   html;

            index  index.html index.htm;

                            proxy_pass                  http://backend; 

           proxy_redirect              off;

           proxy_set_header            Host $host;

           proxy_set_header            X-real-ip $remote_addr;

           proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

                     # proxy_set_header            X-Forwarded-For $http_x_forwarded_for;

        }

咱们来一条条的看

1. proxy_set_header    X-real-ip $remote_addr;

这句话以前已经解释过,有了这句就能够在web服务器端得到用户的真实ip

可是,实际上要得到用户的真实ip,不是只有这一个方法,下面咱们继续看。

2.  proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

咱们先看看这里有个X-Forwarded-For变量,这是一个squid开发的,用于识别经过HTTP代理或负载平衡器原始IP一个链接到Web服务器的客户机地址的非rfc标准,若是有作X-Forwarded-For设置的话,每次通过proxy转发都会有记录,格式就是client1, proxy1, proxy2,以逗号隔开各个地址,因为他是非rfc标准,因此默认是没有的,须要强制添加,在默认状况下通过proxy转发的请求,在后端看来远程地址都是proxy端的ip 。也就是说在默认状况下咱们使用request.getAttribute("X-Forwarded-For")获取不到用户的ip,若是咱们想要经过这个变量得到用户的ip,咱们须要本身在nginx添加以下配置:

proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

意思是增长一个$proxy_add_x_forwarded_for到X-Forwarded-For里去,注意是增长,而不是覆盖,固然因为默认的X-Forwarded-For值是空的,因此咱们总感受X-Forwarded-For的值就等于$proxy_add_x_forwarded_for的值,实际上当你搭建两台nginx在不一样的ip上,而且都使用了这段配置,那你会发如今web服务器端经过request.getAttribute("X-Forwarded-For")得到的将会是客户端ip和第一台nginx的ip。

那么$proxy_add_x_forwarded_for又是什么?

$proxy_add_x_forwarded_for变量包含客户端请求头中的"X-Forwarded-For",与$remote_addr两部分,他们之间用逗号分开。

举个例子,有一个web应用,在它以前经过了两个nginx转发,www.linuxidc.com 即用户访问该web经过两台nginx。

在第一台nginx中,使用

proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

如今的$proxy_add_x_forwarded_for变量的"X-Forwarded-For"部分是空的,因此只有$remote_addr,而$remote_addr的值是用户的ip,因而赋值之后,X-Forwarded-For变量的值就是用户的真实的ip地址了。

到了第二台nginx,使用

proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

如今的$proxy_add_x_forwarded_for变量,X-Forwarded-For部分包含的是用户的真实ip,$remote_addr部分的值是上一台nginx的ip地址,因而经过这个赋值之后如今的X-Forwarded-For的值就变成了“用户的真实ip,第一台nginx的ip”,这样就清楚了吧。

最后咱们看到还有一个$http_x_forwarded_for变量,这个变量就是X-Forwarded-For,因为以前咱们说了,默认的这个X-Forwarded-For是为空的,因此当咱们直接使用proxy_set_header            X-Forwarded-For $http_x_forwarded_for时会发现,web服务器端使用request.getAttribute("X-Forwarded-For")得到的值是null。若是想要经过request.getAttribute("X-Forwarded-For")得到用户ip,就必须先使用proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;这样就能够得到用户真实ip。

相关文章
相关标签/搜索