深入http协议二

浏览器缓存机制

Expires

Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。

Cache-control

Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires

  • max-age=[单位:秒 seconds]
    设置缓存最大的有效时间. 类似于 Expires, 但是这个参数定义的是时间大小(比如:60)而不是确定的时间点.单位是[秒 seconds].
  • public
    响应会被缓存,并且在多用户间共享。正常情况, 如果要求 HTTP 认证,响应会自动设置为 private.
  • private
    响应只能够作为私有的缓存(e.g., 在一个浏览器中),不能再用户间共享。
  • no-cache
    响应不会被缓存,而是实时向服务器端请求资源。但是可能会保存到本地。
  • no-store
    在任何条件下,响应都不会被缓存,并且不会被写入到客户端的磁盘里。
  • must-revalidate
    响应在特定条件下会被重用,但是它必须到服务器端去验证它是不是仍然是最新的。
  • proxy-revalidate
    类似于 must-revalidate,但不适用于代理缓存.

Etag/If-None-Match
Last-Modified/If-Modified-Since

参考这篇文章利用HTTP Cache来优化网站,这里有比较详细的介绍

浏览器行为与缓存

浏览器行为与缓存

304和200(from cache)

304和200(from cache)

客户端从服务器请求数据经历如下基本步骤:

  1. 如果请求命中本地缓存则从本地缓存中获取一个对应资源的”copy”;
  2. 检查这个”copy”是否fresh,是则直接返回,否则继续向服务器转发请求。
  3. 服务器接收到请求,然后判断资源是否变更,是则返回新内容,否则返回304,未变更。
  4. 客户端更新本地缓存。

php对页面的缓存进行控制

php设置 Cache_Control 头标示例代码如下:
header('Cache-Control: max-age=3600*24');//缓存1天,表示最大生存期是1天,超过1天浏览器必须去服务器重新读取,这个时间是从用户第一次读取页面时开始计时的  

php设置 Expires 头标示例代码如下:
header('Expires: Mon, 29 Jan 2007 08:56:01 GMT');
//指定过期时间,注意这里使用的是格林威治标准时间  

Last-Modified:文档的最后修改时间
header('Last-Modified: '.gmdate('D, d M Y 01:01:01',$time).' GMT');//使用的是格林尼治时间,$time是指文件添加时候的时间戳  

http 媒体类型(Content-type)

http 媒体类型(Content-type)

多部分媒体类型 Multipart 文件上传
<form method="post" enctype="multipart/form-data">

header头中的数据格式
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXDeO9rtQLFHRKhdJ

$_postphp://input$HTTP_RAW_POST_DATA的区别

http断点续传

Range
用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式:
Range:(unit=first byte pos)-[last byte pos]

Content-Range
用于响应头,指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:
Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]

www-authenticate认证

www-authenticate是一种简单的用户身份认证技术。
优点:方便
缺点:这种认证方式在传输过程中采用的用户名密码加密方式为BASE-64,其解码过程非常简单,如果被嗅探密码几乎是透明的.

示例代码

<?php
if(!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) || $_SERVER['PHP_AUTH_USER'] !='admin' || $_SERVER['PHP_AUTH_PW']!='admin123'){
    Header("WWW-Authenticate: Basic realm=\"USER LOGIN\"");
    Header("HTTP/1.0 401 Unauthorized");
    echo '必须登录!';
} else {
    echo $_SERVER['PHP_AUTH_USER'];
    echo $_SERVER['PHP_AUTH_PW'];
}

Cookie的原理

cookie 是什么?
cookie使用来跟踪用户会话的技术.cookie本身是一小段文本信息,它存在与http协议header头域里,通过http协议来传递.

cookie 用来干什么?
http协议是一种无状态协议,客户端和服务端完成一次会话后,服务器端不知道下次连接到服务端的是不是同一个客户端,需要有个标识能告诉服务端,是哪个客户端连接上了服务端.例如登录用户,需要有个东西标识,那就在客户端保存一个cookie,下次访问的时候随http header一起发到服务端,服务端根据cookie的内容知道了这是某个用户的请求,服务端根据cookie取到该用户的信息,返回给客户端

cookie 工作原理是什么?

以用户登录来举例

  1. 小明访问某一网站 www.aa.com的登录页面, 此时通过浏览器发了一个http request请求,此时http header头域的cookie值可能是空的。
  2. aa.com服务器收到这个请求,并接受了小明提交过来的登录数据,判断用户名和密码都正确,这个时候服务器会“种下一个cookie”。一般是将小明的用户名发给客户端,通常是”Cookie: usernick=xiaoming;”这个字符串通过http response返回给客户端(浏览器)
  3. 浏览器收到http response返回来的信息发现cookie了,然后将该信息写入到浏览器的某个存储文件中
  4. 小明再访问xx.com的其他页面的时候,请求的http header中会带着这个cookie。
    服务器的程序会找cookie,并根据cookie的信息取出信息,验证是否登录。

Session 的原理 

session是什么

Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。

session是怎么工作的

  1. 用户请求login.php填写数据后提交
  2. 服务器收到提交的数据取得用户信息,将用户信息存入session,并将session_id通过cookie的形式发给客户端
  3. 客户端将session_id存入浏览器cookie文件
  4. 用户再次访问其他页面时,将有session_id的cookie通过header头发给服务端
  5. 服务端拿到session_id从session中取到用户信息并返回

session_默认是基于cookie传递的,当用户禁用浏览器cookie时,也可以通过url来传递

session的生成过程

  1. session_start()是session机制的开始。
  2. session会判断当前是否有$_COOKIE[session_name()];
  3. 如果不存在会生成一个session_id,然后把生成的session_id作为COOKIE的值传递到客户端.
  4. 如果存在那么session_id = $_COOKIE[session_name];然后去session.savepath指定的文件夹里去找名字为SESS . session_id()的文件. 读取文件的内容反序列化,然后放到$_SESSION中。

session存储的内容是啥样的
uid|i:123;abc|O:1:”a”:2:{s:1:”s”;s:4:”test”;s:1:”b”;a:2:{i:0;s:2:”12″;i:1;s:2:”34″;}}

session中怎么存储的
序列化serialize

问题1.session的有效期?
由php.ini中的session配置决定

问题2.关闭客户端可以删除session或者使session失效吗?
不能删除session,但有可能使session失效 .使其失效的原因是如果配置的session有效期是cookie随着浏览器失效.

问题3.如果浏览器不支持cookie,session能正常使用吗?
可以,将session通过url传递

问题4.如果服务端有多台服务器,session如何共享?
nfs, 将多台服务器所在的session存储目录设置为mount挂载的目录
memcache,session.save_handler = memcache并设置路径session.save_path = “tcp://192.168.1.101:11211″
mysql,ession.save_handler = user,然后建立session表,建立php文件用于对数据库表操作session数据,最后用session的都引入上一步中的php文件

 HTTP安全-HTTPS

为了避免HTTP协议在传输过程中被抓包解析,此时可以通过HTTPS协议来保证数据在传输过程中的安全

HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版。

例如https://login.taobao.com/member/login.jhtml  
https 表明他是用的http协议,只不过走的是安全通道

HTTPS传输协议原理

HTTP原先 直接建立在tcp协议上

HTTPS 建立在ssl协议上,当然ssl协议也是建立在tcp协议上
首先我们有两种基本的加解密算法类型:对称加密,非对称加密(公私钥加密)。

对称加密

密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密
算法有DES、AES等,示意图如下:
对称加密

非对称加密

非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),
加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密
速度较慢,典型的非对称加密算法有RSA、DSA等,示意图如右:
非对称加密

HTTPS传输协议原理介绍

根据上面的两种加密方法,现在我们就可以设计一种无法让他人在互联网上知道你的通讯信息的加密方法:

  1. 在服务器端存在一个公钥及私钥
  2. 客户端从服务器取得这个公钥
  3. 客户端产生一个随机的密钥
  4. 客户端通过公钥对密钥加密(非对称加密)
  5. 客户端发送到服务器端
  6. 服务器端接受这个密钥并且以后的服务器端和客户端的数据全部通过这个密钥加密(对称加密)

SSL协议的工作流程

  1. 客户端向服务器请求获取证书+公钥
  2. 客户端通过CA验证收到证书的合法性
  3. 客户端通过收到的公钥加密一个字符串,作为后续通信密钥,发送给服务器
  4. 服务器通过私钥解密,得到通信密钥
  5. 后续HTTP协议通过通信密钥加密进行

HTTPS通信过程的时序图

HTTPS通信过程的时序图

我们能保证下面几点:

  • 客户端产生的密钥只有客户端和服务器端能得到
  • 加密的数据只有客户端和服务器端才能得到明文
  • 客户端到服务端的通信是安全的

HTTP 安全-常见的攻击方式

xss 跨站点脚本攻击、csrf 跨站请求伪造

xss跨站点脚本攻击

防止xss

  • 不要相信用户输入的任何内容
  • 将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了.
  • 只允许用户输入我们期望的数据。 例如: 年龄的textbox中,只允许用户输入数字。 而数字之外的字符都过滤掉。
  • 对数据进行Html Encode 处理
  • 过滤或移除特殊的Html标签, 例如: <script>, <iframe> , &lt; for <, &gt; for >, &quot for
  • 过滤JavaScript 事件的标签。例如 “onclick=”, “onfocus” 等等。

csrf跨站请求伪造

防范措施

  • 随机数token
  • 验证码
  • 表单提交
  • reffer

参考文章

HTTP 缓存
利用HTTP Cache来优化网站
Caching Tutorial for Web Authors and Webmasters
RFC文章