客户端识别与cookie机制(HTTP权威指南)
一、客户端识别
每天都有数以亿计的客户端与Web服务器通信,服务器是怎么知道它在和谁对话呢?
- 承载用户身份信息的HTTP首部
- 客户端 IP,通过用户的 IP 地址对其进行识别
- 用户登录,用认证的方式识别用户
- 胖 URL,在 URL 中嵌入识别信息的技术
- cookie
承载用户信息的首部有 From(用户的E-mail地址)、Authorization、Client-IP、Cookie。
以 From 为例,每个用户都有不同的邮箱地址,按理来说是可以标识用户的,但为什么不用呢?
Web 服务器并不都是善意的,有些恶意服务器会收集这些邮箱,然后发送令人厌恶的广告,另外也是不安全的。
然后是客户端 IP 也就是 Client-IP 首部,这个很容易想到,一个 IP 只能代表一个客户端,不能代表用户。
再然后就是用户登录,也就是 Authorization 首部,这里详细说一下:
当用户访问一个资源时,比如个人信息,这时服务器就会要求用户登录,输入用户名和密码等信息。
只要用户输入了用户名和密码,浏览器就会重复原请求,并添加 Authorization 首部,值为用户名和密码的 Base64 加密。
今后的请求要登录时,浏览器就会把 Authorization 首部及其值发送出去。甚至没要求登录时也会发送出去。
以上谈到 Authorization 的值为 Base64 加密,该加密是可逆的,所以并不安全。
什么是胖 URL 呢?举个例子吧:
<a href="/exec/obidos/tg/browse/-/229220/ref=gr_gifts/002-114565-8016838">All Gifts</a>
比如上面的 002-114565-8016838 就是一个标识码,每个用户访问都不同。这就被称为胖 URL。
这种方式有很明显的缺点:丑陋、该 URL 不可以共享,否则将会泄漏个人信息、没有公共的缓存、服务器要重写 HTML增加负荷......
二、Cookie
好啦,下面重点来了,cookie 是当前识别用户并实现持久会话的最好方式,我们来介绍一下它:
可以笼统的将 cookie 分为两类:会话 cookie 和 持久 cookie。
会话 cookie 是一种临时 cookie,用户退出浏览器时,会话 cookie 就被删除了。
持久 cookie 存储在硬盘上,浏览器退出,计算机重启时它仍在,不过它有一个过期时间。
如果设置了 Discard 参数,或者没有设置 Expires 或 Max-Age 参数来说明扩展的过期时间,这个 cookie 就是会话 cookie。
同胖 URL 思路一样,也是给访问的用户打上一个标签。cookie 中包含了一个由 name=value 这样信息构成的任意列表。
并通过 Set-Cookie 或 Set-Coookie2 HTTP响应(扩展)首部将其贴到用户身上去。
以 Google 浏览器为例:
Name | cookie 的名字 |
Value | cookie 的值 |
Domain | cookie 的域,那些站点可以看到 cookie |
Path | 域中与 Cookie 相关的路径前缀,那些域前缀可以看到 cookie |
Expires/Max-Age | Expires 是过期日期,Max-Age 是过期剩余秒数 |
Size | 此 cookie 的大小,不知道怎么算的哈 |
HttpOnly | 是否 js 脚本可以读取该 cookie |
Secure | 是否只有在使用 SSL 连接时才发送这个 cookie |
SameSite | 用来防止 CSRF 攻击和用户追踪 |
Priority | cookie 的优先级,当 cookie 数量超出时,优先级最低的会被删掉 |
以上属性需要详细解释一下的就是 Domain 和 Path:
浏览器内部的 cookie 罐中可以有成百上千个 cookie,但浏览器不会将每个 cookie 都发送给所有的站点。
总之,浏览器只向服务器发送服务器产生的那些 cookie。
1、Domain 属性
比如下面这个HTTP响应首部就是告诉浏览器将 cookie user="mary17" 发送给域 “.airtravelbargains.com” 中的所有站点。
Set-cookie: user="mary17"; domain="airtravelbargains.com"
如果用户访问的是 www.airtravelbargains.com、specials.airtravelbargains.com 或任意以 .airtravelbargains.com 结尾的结点,
Cookie: user="mary17" 都会被发布出去。
2、Path 属性
例如,某个 Web 服务器可能是两个组织共享的,每个组织都有独立的 cookie。
Set-cookie: pref=compact; domain="airtravelbargains.com"; path="/autos/"
如果用户访问 http://www.airtravelbargains.com/specials.html,就只会获得这个 cookie: Cookie: user="mary17"
如果用户访问 http://www.airtravelbargains.com/autos/cheapo/index.html,就会获得两个 cookie:
Cookie: user="mary17"
Cooke: pref="compact"
3、Cookie 有两个版本:Set-cookie、Set-cookie2,区别就是首部的 Name 不同,还有就是后者属性更多一些。
三、安全 HTTP
HTTPS 是最流行的 HTTP 安全形式,HTTPS 的 URL 是以 https://,而不是 http:// 开头。
使用 HTTPS 时,所有的 HTTP 请求和响应数据在发送到网络之前,都要进行加密。
HTTPS 在 HTTP 下面提供了一个传输级的密码安全层,可以使用 SSL,也可以使用 TLS(TLS 是 SSL 的升级版)。
大部分困难的编码以及解码工作都是在安全层完成的,所以 Web 客户端和服务器无需过多的修改其协议处理逻辑。
四、密码
任意两人之间要进行私密通信,都需要一个只有彼此才能理解的语言。
比如循环移位(n) 编码器:
// 密钥=1,右移1位
明文:Meet me at the pier at midnight。
密文:nffu nf bu uif qjfs bu njeojhiu。
// 密钥=2,右移2位
明文:Meet me at the pier at midnight。
密文:oggv og cv vig rkgt cv okfpkijv。
// 密钥=3,右移3位
明文:Meet me at the pier at midnight。
密文:phhw ph dw wkh slhu dw plgqlijkw。
给定一段明文报文 P、一个编码函数 E 和一个数字编码密钥 e,就可以生成一段经过编码的密文 C。
通过解码函数 D 和解码密钥 d,就可以将密文 C 解码为原始的明文 P。
1、对称密钥加密技术
对称密钥加密技术是指,编码时和解码时的密钥时一样的,常见的有 DES、RC2、RC4。
缺点:如果很多人要和 web 站点通信,那每个人和 web 站点都要建立一个私有密钥,数量将是很庞大的。
2、公开密钥加密技术
公开密钥加密技术没有为每对主机使用单独的加密/解密密钥,而是使用了两个非对称密钥,常见的有 RSA。
一个用来对主机报文编码,一个用来对主机报文解码。编码密钥是众所周知的,但是只有主机才知道私有的解密密钥。
五、数字签名
数字签名是附加在报文上特殊加密效验,用来说明是谁编写的报文,同时证明报文未被篡改过。
数字签名通常是用非对称公开密钥技术产生的。因为只有所有者才知道其私有密钥,所有可以将作者的私有密钥当作一种指纹使用。
六、数字证书
典型的数字证书如下格式:
证书版本号 -----------------------|
证书序列号 -----------------------|
证书签名算法 --------------------|
证书颁发者 ---------------------------》 数字签名函数
有效期 -----------------------------| |
对象名称 --------------------------| |
对象公开密钥 --------------------| |
其他扩展信息 --------------------| |
数字签名 《---------------------------------------|
通过 HTTPS 建立了一个安全 Web 事务后,现代浏览器都会自动获取所连接服务器的数字证书。
如果服务器没有证书,安全连接就会失败。
七、HTTPS 细节介绍
HTTPS 就是在安全的传输层上发送的 HTTP,安全层是通过 SSL 或其替代协议 TLS 来实现的。
URL 为 http 开头的,默认情况下客户端会打开一条到服务器 80 端口的连接。
URL 为 https 开头的,默认情况下客户端会打开一条到服务器 443 端口的连接。
如果没有安全层,HTTP 的传输时非常简单的,在建立连接后,发送一条请求报文,接收一条响应报文,最后关闭连接就完事了。
因为有了安全层,建立连接后,客户端和服务器就会初始化 SSL\TSL 层,对加密参数进行沟通,互换密钥。
SSL握手完成后,SSL 初始化就完成了,客户端就可以把请求报文发送给安全层了,在将这些报文发送给 TCP 之前,要对其进行加密。
SSL握手的过程:1、交换协议版本号,2、选择一个两端都了解的密码,3、对两端身份进行认证,4、生成临时会话密钥,加密信道。
SSL 支持双向认证,将服务器证书承载回客户端,再将客户端证书回送给服务器。
但是浏览时并不经常使用客户端证书,大部分用户甚至都没有自己的客户端证书,但是安全 HTTPS 事务总是要求使用服务器证书的。