测试代码:
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/”