http请求头的Host,Referer,Origin:
Host:指定请求服务器的域名/IP地址和端口号。
作用:
同一台机器上,可能部署多个服务,通过解析host+端口,指定具体访问的站点。
host的要点:
-
HTTP/1.0不带host,HTTP/1.1新增host头。
-
host可以是域名,也可以是IP地址,Host字段域名/ip后可以跟端口号,如Host: www.sina.com:8080
-
host可以由程序自定义,某些程序为了防止运营商或者绕过防火墙,可以定义虚假host。
-
HTTP/1.1中的host可以为空值但不可以不带。如果不带host头,会返回400 Bad request。
-
http请求头包含host字段,响应头不包含host字段。
-
部分站点不校验host,可以传任意值。
重点解析:Host用来实现虚拟主机技术。
虚拟主机(virtual hosting)即共享主机(shared web hosting),可以利用虚拟技术把一台完整的服务器分成若干个主机,因此可以在单一主机上运行多个网站或服务。
host字段表示目标服务器域名。我们知道一般服务器都只会有一个ip地址,而一个ip地址可以有多个域名(站点),比如我们有www.baidu.com,www.taobao.com和www.jd.com几个域名,在域名供应商那通过A记录或者CNAME方式记录与服务器的ip地址关联,那么通过任何一个域名访问最终解析到的都是该ip。
举个栗子,有一台 ip 地址为 61.135.169.125 的服务器,在这台服务器上部署着百度、淘宝,京东的网站。为什么我们访问“www.baidu.com”时,看到的是 百度 的首页而不是淘宝或京东的首页?原因就是 Host 请求头决定着访问哪个虚拟主机。如果服务器后台解析出Host但是服务器上找不到相应的站点,那么这个连接很可能会被丢弃,从而报错。
综上所述,个人理解host字段是代表你的请求将要到哪台(虚拟)主机,并会在服务端被验证,如果不符合,就不能正确处理客户端的请求。
nginx config配置中内置变量host的坑
我们在配置nginx的配置时,一般是这样的。举例:
server {
listen 80;
server_name mirrors.maqian.work;
location / {
proxy_pass http://mirrors.aliyun.com;
proxy_redirect off;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
proxy_set_header Host $host这一行的作用是把原http请求的Header中的Host字段也放到转发的请求里。如果不加这一行的话,nginx转发的请求header里就不会有Host字段,而服务器是靠这个Host值来区分你请求的是哪个域名的资源的。
http_host和$proxy_host区别
变量 | 是否显示端口 | 值 |
---|---|---|
content1 | content2 | content3 |
$host | 不显示端口 | 浏览器请求的ip,不显示端口 |
$http_host | 端口存在则显示 | 浏览器请求的ip和端口号 |
$proxy_host | 默认80端口不显示,其它显示 | 被代理服务的ip和端口号 |
这里,我们报400错误,直接删除proxy_set_header Host $proxy_host; 解决
因为是在容器中,这里重新设置请求头的信息会有问题,因为主机名就会有问题。
Referer:
HTTP Referer是头部的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。
Referer其实应该是英文单词Referrer,不过拼错的人太多了,所以编写标准的人也就将错就错了。获取Referer:document.referrer
作用:
1.统计访问流量等。
Http协议头中的Referer主要用来让服务器判断来源页面, 即用户是从哪个页面来的,通常被网站用来统计用户来源,是从搜索页面来的,还是从其他网站链接过来,或是从书签等访问,以便网站合理定位.
2.防盗链
Referer有时也被用作防盗链, 即下载时判断来源地址是不是在网站域名之内, 否则就不能下载或显示,很多网站,如天涯就是通过Referer页面来判断用户是否能够下载图片.
当然,对于某些恶意用户,也可能伪造Referer来获得某些权限,在设计网站时要考虑到这个问题.
3.安全验证,防止恶意请求
还可用做电子商务网站的安全,在提交信用卡等重要信息的页面用referer来判断上一页是不是自己的网站,如果不是,可能是黑客用自己写的一个表单,来提交,为了能跳过你上一页里的javascript的验证等目的。
但是注意不要把Rerferer用在身份验证或者其他非常重要的检查上,因为Rerferer非常容易在客户端被改变。 (火狐的一个插件RefControl修改Referer引用)
Referer为空的情况:
http头部中没有Referer:
根据Referer的定义,它的作用是指示一个请求是从哪里链接过来,那么当一个请求并不是由链接触发产生的,那么自然也就不需要指定这个请求的链接来源。或者页面从Https跳转到Http;处于安全考虑。某些浏览器(IE)会没有Referer
比如,直接在浏览器的地址栏中输入一个资源的URL地址,那么这种请求是不会包含 Referer 字段的,因为这是一个“凭空产生”的 HTTP 请求,并不是从一个地方链接过去的。或者从收藏夹/书签中访问。
Referer内容为空:
允许设置为 Referer 为空,意味着你允许比如浏览器直接访问,就是空。
Origin:
HTTP 头部的 Origin ,用于指明当前请求来自于哪个站点。
Origin 仅仅包含站点信息,不包含任何路径信息。(一般跨域请求会出现origin)
作用:
1.CORS跨域请求校验Origin判断请求来源。
当我们的浏览器发出跨站请求时,行为正确的服务器会校验当前请求是不是来自被允许的站点。服务器就是通过 Origin 字段的值来进行的判断。
当服务器的配置出错时,比如配置成了 https://baidu.com/,则可能造成一些难以理解的问题。(正确配置:Origin: “https://baidu.com”)
比如有的浏览器(IE)能够请求成功,而有的浏览器却请求失败(Chrome)。成功是因为前一个浏览器发出请求时没有带上 Origin, 而后一个浏览器带上了正确的 Origin。在服务器端,因为没有 Origin Header,所以认为这不是一次 CORS 请求,所以没有进行 CORS 校验,直接请求。所以,我们要求服务端请求带上 Origin Header,才能进一步保证服务器的安全性。
2.防御CSRF(跨域请求伪造)攻击。
如果 Origin 存在,可以直接使用 Origin 中的字段确认来源域名。
用Origin字段的方法来防御CSRF攻击的时候,网站需要做到以下几点:
- 在所有能改变状态的请求里,包括登陆请求,都建议使用POST方法。
- 对于那些有Origin字段但是值并不是我们希望的(包括值为空)请求,建议服务器要拒绝。比如,服务器可以拒绝一切Origin字段为外站的请求。
Host,Referer,Origin的简单对比区别:
需要使用这三者的场景:
- 处理跨域请求时,必须判断来源请求方是否合法;
- 后台做重定向时,需要原地址信息;
区别:
- Host 描述请求将被发送的目的地,包括,且仅仅包括域名和端口号。 在任何类型请求中,request都会包含此header信息。
- Origin 用来说明请求从哪里发起的,包括,且仅仅包括协议和域名。 这个参数一般只存在于CORS跨域请求中,可以看到response有对应的header:Access-Control-Allow-Origin。
- Referer 告知服务器请求的原始资源的URI,其用于所有类型的请求,并且包括:协议+域名+查询参数(注意,不包含锚点信息)。因为原始的URI中的查询参数可能包含ID或密码等敏感信息,如果写入referer,则可能导致信息泄露。