使用代理和不使用代理request获取host、scheme、url、ip区别

时间:2024-11-01 07:18:25

测试代码:

		String host = getRequest().getHeader("Host");
		System.out.println("host:" + host);
		String scheme = getRequest().getScheme();
		System.out.println("scheme:" + scheme);
		String forwardedProto = getRequest().getHeader("X-Forwarded-Proto");
		System.out.println("forwardedProto:" + forwardedProto);
		String url = getRequest().getRequestURL().toString();

浏览器输入:http://127.0.0.1:8080/xpl/demo/dynamicCondition

打印结果:

host:127.0.0.1:8080
scheme:http
forwardedProto:null
url:http://127.0.0.1:8080/xpl/demo/dynamicCondition

使用nginx代理,代理主要配置:

    server {
        listen       443 ssl;
        server_name  my.com;

        ssl_certificate      20241028.pem;
        ssl_certificate_key  20241028.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
        
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        location /xpl/demo/dynamicCondition {
            proxy_pass   http://192.168.5.55:8080;

            root   html;
            index  index.html index.htm;
        }

浏览器输入:https://my.com/xpl/demo/dynamicCondition 

打印结果:

host:my.com
scheme:http
forwardedProto:https
url:http://my.com/xpl/demo/dynamicCondition

结论:

 1.从浏览器输入请求地址访问时,浏览器会自动在请求头中添加Host属性,属性值对应请求地址主机地址(有端口号的话,包括端口号)。即http(s)://{主机地址}/。

2.getRequest().getHeader("Host")就是从请求头中获取对应的Host属性。

3.nginx代理如果不配置proxy_set_header Host $http_host;,那么后面打印的应该就是:

192.168.5.55:8080

而不是: 

my.com

 4.默认浏览器发送的请求头中X-Forwarded-Proto应该是没有值的。一般都是代理加上的。

5.getRequest().getScheme()如果web服务器如果没有做ssl配置的话,一般都是返回http。

6.getRequest().getRequestURL()方法前面的协议是与getRequest().getScheme()一致的,即可能与浏览器输入的地址不一样。没有深入的分析源码,初步猜测应该是:

{getScheme()}://{Host}/{getRequestURI()}

 以上结论,是通过上面测试得出的。下面还有些结论就没写具体测试过程了。

关于ip地址

1.request.getRemoteAddr()获取客户端ip地址。这个是tcp/ip网络层协议中获取的ip地址,是请求发出终端的ip地址。无法伪造的。如果使用了代理,返回的就是代理的地址。

2.使用代理的情况,要如何获取用户真实的ip地址呢?这个就要代理服务器告诉你了。需要的代理服务器约定好,比如request.getHeader("X-Real-IP")或者request.getHeader("x-forwarded-for")或者request.getHeader("Proxy-Client-IP")等方法了。具体使用哪种方法得看代理服务器了。上面例子用的是请求头中加入X-Real-IP属性。

3.使用代理获取的用户真实ip地址,有可能被伪造的。比如代理可以在请求头的X-Real-IP属性写入任意ip地址,并不一定是用户真实的ip地址。即如果对用户真实ip地址准确的有严格要求的话,要对代理服务器进行验证,避免伪造代理服务器发起请求,获取到错误的用户ip地址。

关于getRequest().getRequestURI()

1.该方法不会返回空字符串,即使浏览器输入地址

http://127.0.0.1:8080

或者

http://127.0.0.1:8080/

返回值都是"/" 

2.返回值截止至“?”,不包含“?”。例如:

http://127.0.0.1:8080/xpl  返回值是  “/xpl”

http://127.0.0.1:8080/xpl?a=3  返回值是  “/xpl”

http://127.0.0.1:8080/xpl/  返回值是  “/xpl/”

http://127.0.0.1:8080/xpl/?a=3  返回值是  “/xpl/”