Session与Cookie状态管理中的加盐(salt)
一种安全的保存方法是,先利用给密码加盐的方式增加额外信息,再使用散列(hash)函数计算出散列值后保存。但是我们也经常看到直接保存明文密码的做法,而这样的做法具有导致密码泄露的风险。
注释;salt是由服务器随机生成的一个字符串,但是要保证长度足够长,并且是真正随机生成的。然后把它和密码字符串相连接(前后都行)生成散列值。当两个用户使用了同一个密码时,由于随机生成的salt值不同,对应的散列值也将不同。这样一来,很大程度上减少了密码特征,攻击者也就很难利用自己手中的密码特征库进行破解。
SPDY
SPDY旨在解决HTTP性能瓶颈,缩短Web页面的加载时间。
你可能会想到,为了能实时获取服务器上的内容更新,需要不断地请求服务器。但是HTTP无法妥善处理好这项工作。使用HTTP探知服务器上是否有内容更新,就必须频繁地从客户端到服务端进行确认。如果服务器上没有内容更新,那么就会产生徒劳的通信。
这样的需求使得使用HTTP成为一种瓶颈,会存在如下问题:
- 一条连接上只可发生一个请求;
- 请求只能从客户端开始且客户端不可以接收除了响应以外的指令。
- 请求/响应首部有时未经压缩就发送,如果首部信息越多,延迟就会越大。
- 每次要发送相同的、冗长的首部,会造成浪费较多;
- 非强制压缩的情况下,可任意选择数据压缩格式。
当然,也有相应的办法,如Ajax(核心技术是XMLHTTPRequest的API)。由于AJAX只更新一页面的一部分,所以响应中传输的数据量会因此减少。但是,这也会带来一些问题,即它可能会导致大量请求的产生。除此之外,Ajax仍未解决HTTP协议本身存在的问题,即Ajax每次请求时,都会与服务端互相发送相同的首部,有时服务端在响应时,对数据不压缩就直接发送了。
接着往下看解决方法的寻找。
Comet解决方法
Comet是一种通过延迟应答,模拟实现服务器端向客户端推送的功能。一旦服务端有更新,Comet不会让请求等待,而是直接给客户端返回响应。
Comet是如何实现推送功能的呢?通常,Comet会将服务端的响应置于挂起状态,当服务端有更新时,再返回响应。这样做虽然能做到实时更新,但是为了保留响应,一次连接的持续时间也会变长。而Comet并没有解决这个问题。
SPDY
要做根本性的改变,处理HTTP的瓶颈,必须改写HTTP协议。但是SPDY并没有完全改写HTTP,而是在TCP/IP的应用层与运输层之间加入会话层,并使用SSL进行通信,而连接上还是采用HTTP。
SPDY以会话层的形式加入,是为了控制数据的流动。通过使用SPDY,它能让单一的TCP处理无限制的多个HTTP请求,还可以给请求逐个分配优先级顺序,并且压缩HTTP请求和响应的首部。另外,就是支持服务端向客户端的推送功能。
但是,很多Web网站存在的问题并非仅仅是由HTTP瓶颈造成的,对Web本身的速度提升,还应该从其他细致的地方入手,例如改善Web内容的编写方式。
WebSocket
Ajax和SPED虽然能提升HTTP的通信速度,但是却无法完全地解决HTTP的瓶颈问题。
WebSocket的出现正式为了这些问题而生的。WebSocket协议是Web浏览器与服务器之间全双工通信标准,其主要为了解决Ajax和Comet里XMLHttpRequest附带的缺陷所引起的问题。
一旦Web 服务器与客户端之间建立起WebSocket协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可相互发送JSON、XML、HTML或图片等任意格式的数据。
由于是建立在HTTP基础上的协议,因此连接的发起方仍是客户端,而一旦确定WebSocket通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。
- 推送:服务端向客户端推送,不必等待客户端请求。
- 减少通信量:因为一旦建立起WebSocket连接,就希望保持连接。所以,每次连接时总开销减少,并且WebSocket的首部信息很小,所以通信量随之减少。
- 握手·请求:为了实现WebSocket通信,需要用到HTTP的Upgrade首部字段,告知服务器通信协议发生改变,以达到握手目的。(
Upgrade:websocket
) - 握手·响应:对于改变通信协议的请求,服务端会返回状态码101 Switching Protocols 的响应。
(HTTP/1.1 101 Switching Protoclos
)
Websocket API
javascript可调用有W3C制定的The WebSocket Api内提供的WebSocket程序接口,实现WebSocket协议的全双工通信。例如:每30ms发生一次数据
let socket = new WebSocket('ws://www.abc.com/updates'); socket.open = function() { setInterval(function(){ if(socket.bufferedAmount==0) socket.send(getUpdateData()); },30); };