@yangfch3
2015-12-05T18:01:54.000000Z
字数 4922
阅读 4115
JavaScript
HTTP
连接是无状态连接,没有记忆功能。服务端在无其他措施的情况下,无法记住同一客户端的前次的请求,也无法识别特定的不同用户。
每次会话都是全新的。
以一次登陆 Github
的角度分析 Cookie
作用的全过程:
打开 Github
,未登录之前,打开 Network
界面,查看首页 Request Header
的 Cookie
信息:
Cookie:logged_in=no; _gh_sess=eyJzZXNzaW9uX2lkIjoiZDk0NzYzMTIxYzNiNTk3ZjNkMzFhZjM2OTJlZmIxNDMiLCJfY3NyZl90b2tlbiI6IllWaEs2Q3UvNmxObFQwQnU5R0pqcTNPOWhiZU9HMkVmS2dpbWpvOUh6ZEk9In0%3D--d3f50c5a83a5f5bf3766564ddc4bbf5d8f70f832; _octo=GH1.1.797316355.1449214528; _ga=GA1.2.202017092.1449214528; _gat=1; tz=Asia%2FShanghai
里面很清晰地可以看到:logged_in=no;
登陆后再次查看首页的请求头的 Cookie
信息
Cookie:_octo=GH1.1.797316355.1449214528; _gat=1; logged_in=yes; dotcom_user=yangfch3; user_session=L-H83S3FP-km8Y4qcOgjDZxWaNxTWfhRH-Cmsgu--09GleIvVmFC0Ca2iYIY_R7EZOrz66z6rMKdlvUV; _gh_sess=eyJsYXN0X3dyaXRlIjoxNDQ5MjE0NjcyMTk5LCJzZXNzaW9uX2lkIjoiN2YyYzExYTM4OGQ3ZTZiNWNkNTQ4YmM1ZGVmZDg1YjUiLCJjb250ZXh0IjoiLyIsImZsYXNoIjp7ImRpc2NhcmQiOlsiYW5hbHl0aWNzX2xvY2F0aW9uIl0sImZsYXNoZXMiOnsiYW5hbHl0aWNzX2xvY2F0aW9uIjoiL2Rhc2hib2FyZCJ9fX0%3D--4c5443839a61e148dd7eaba11d0fa4d52285c311; _ga=GA1.2.202017092.1449214528; tz=Asia%2FShanghai
此时可以看到键值对:logged_in=yes;dotcom_user=yangfch3;...
查看首页的响应头的 setCookie
信息
Set-Cookie:user_session=TOaMilSO3HrprRwMgUB5c-BhvWfWzdX3q6949y8BZJIxagvxVmGV4-J6eWN9_EsEaxMZHsx_Piogt_SR; path=/; expires=Fri, 18 Dec 2015 13:32:19 -0000; secure; HttpOnly
我们再查看一下其他资源(例如图片、CSS、JS...)的 Cookie
,例如:octocat_setup.png
Cookie:_octo=GH1.1.797316355.1449214528; _gat=1; logged_in=yes; dotcom_user=yangfch3; _ga=GA1.2.202017092.1449214528
点击某个与个人有关的链接,这回我们看页面响应头的 Cookie
信息以及页面请求头的 setCookie
信息:
Set-Cookie:_gh_sess=eyJsYXN0X3dyaXRlIjoxNDQ5MjE0NjcyMTk5LCJzZXNzaW9uX2lkIjoiN2YyYzExYTM4OGQ3ZTZiNWNkNTQ4YmM1ZGVmZDg1YjUiLCJjb250ZXh0IjoiLyIsInNweV9yZXBvIjoieWFuZ2ZjaDMvTGVhcm4tTW9kZXJuaXpyLURlbW8iLCJzcHlfcmVwb19hdCI6MTQ0OTIxNTI4MiwiZmxhc2giOnsiZGlzY2FyZCI6WyJhbmFseXRpY3NfbG9jYXRpb24iXSwiZmxhc2hlcyI6eyJhbmFseXRpY3NfbG9jYXRpb24iOiIvPHVzZXItbmFtZT4vPHJlcG8tbmFtZT4ifX19--5f567b45e73dd027cd9be4b244cfc85db2b33d95; path=/; secure; HttpOnly
Set-Cookie:user_session=L-H83S3FP-km8Y4qcOgjDZxWaNxTWfhRH-Cmsgu--09GleIvVmFFMvrZj6Kj2YAMywmqTBJA9bcPlPFw; path=/; expires=Fri, 18 Dec 2015 07:48:02 -0000; secure; HttpOnly
登陆过程详解:
- 打开
github.com
登录页,浏览器寻找本机Cookie
;如果能找到,则把Cookie
写入请求头,再向服务器发起请求,如果未在本机上找到对应网站的Cookie
,则直接发起请求- 服务器接收到请求(
Request
),检查请求头(request header
)有无Cookie
信息:
- 无:返回登陆界面,由用户填写表单,接下来进入 ③ (正是示例中的情况)
- 有:根据
Cookie
解析出来的用户信息,为用户返回定制化的个人首页- 用户填写好表单,发送到服务器进行验证;服务器根据用户提交的表单,核对数据库中的信息,返回根据用户信息的定制化主页,同时服务器产生
Cookie
,写入返回的主页的响应头(response header
)- 浏览器接收到定制化主页后,将该站点
Cookie
存入特定的文件区域,方便下次访问调取Cookie
和setCookie
分别反应在请求头和响应头上
从上,我们可知道 Cookie
的一些明显特征:
Cookie
一般是服务器生成,写入到返回文件的响应头(response header
)里;Cookie
作为文本信息由客户端(浏览器)存储在特定的区域,不同的网站的 Cookie
一般存储在不同区域,一个网站只能由浏览器读取他本站的 Cookie
,无法从其他 Cookie
文件中取得信息Cookie
就像身份证,服务器则是 身份证检测仪
,所以一般 Cookie
包含了一些已经经过加密的用户信息,一般只能由对应服务器进行解密,方便服务器端根据用户实现定制化的功能Cookie
是与 Web
站点(域名)关联而不是某个具体页面相关联的Cookie
是非明文可见的(在请求头和响应头),可通过脚本等手段修改的Cookie
是维持 Web
服务器连续性的方法,解决 HTTP
无状态的措施Cookie
是文档 document
的一个属性,存储在 document
的 Cookie
属性内,本质是字符串,同时也是浏览器通过 Javascript
可以操控的一个对象。
键值对,name:value
形式,分号隔开,最多存储20对 name:value
键值对
[expirse=date];
:过期时间;如果不使用,则关闭浏览器后,该 Cookie
自动消失[path=dir];
:Cookie
对服务器那个目录下的页面有用,设定后对该目录及子目录所有页面有效[domain=domainname];
:设置相同域名的多台服务器共享一个 Cookie
[secure=true]
:表示 Cookie
只能通过使用 HTTPS
或者其他安全协议的 Internet
连接来传输,未使用该属性则说明 Cookie
传输未加密chrome
的 Cookie
保存路径:
C:\Users\YFCODE\AppData\Local\Google\Chrome\User Data\Default
一般浏览器都可以进行注册表 Cookie
禁用、全局 Cookie
禁用,或者针对特定站点的 Cookie
禁用
name:value
字符串写入 Cookie
var txt = "logged=yes;user=yangfch3;";
document.cookie = txt;
// 并不会覆盖原来的 Cookie ,只是会自动添加到原 Cookie 的后面
每对键值对以分号结束,每对键值对之间以一个空格隔开
name1=value; name2=value2; ...
键值对内部不能包含:分号、逗号和空格
value
中包含这些字符时,使用 encodeURI
对特殊符号进行编码,读取时使用 decodeURI
进行解码:
document.cookie = encodeURI("test=value")+";expires="+date.toUTCString();
使用 Date
对象获取到的时间对象格式含有大量空格,需要使用 Date
对象的方法将其转换为普通字符串
domain
可以用于设置多服务器共享 Cookie
cookie
还可以用于存储用户填写的表单,防止误操作或者上传不成功刷新而导致的表单丢失
方法是用户在填写表单时,将表单的键与值按一定格式存储到
cookie
,之后再用JS
读取利用
Cookie
—— 返回的是字符串
var cookieString = document.cookie;
// "user=yangfch3; logined=yes; bdshare_firstime=1449300282369"
function readCookie(){
var cookieString = decodeURI(document.cookie); // 或用 toString();
var cookieArr = cookieString.split(";");
for(x in cookieArr){
cookieArr[x] = cookieArr[x].split("=");
}
return cookieArr;
}
// [["user","yangfch3"],["logined","yes"],["bdshare_firstime","1449300282369"]]
Cookie
删除一个 Cookie
的方法是:将 Cookie
过期时间(expirse
)设为过去的一个时间,使得 Cookie
过期失效,从而实现删除
function deleteCookie(){
var date = new Date();
date.setTime(date.getTime()-10000000); // 设定一个过去的时间
document.cookie = "expires=" + date.toGMTString();
}
Cookie
存储账户信息(如密码等),使用明码容易被截取,十分危险;
解决方法:所以一般的
Cookie
都是用MD5
加密,即使被截取也比较难破解。
Cookie
欺骗:中间人截取 Cookie
信息,使用该 Cookie
信息与服务器通信,这样你就被冒充了。Cookie
服务器难以排查 Cookie
欺骗,常见的实现 Cookie
欺骗的方法为:XSS
攻击、Flash
恶意代码
解决方法:
- 打开本地防火墙;
- 减少或杜绝浏览不知名或恶意站点;
- 寻找可靠的大型
ISP
;- 不要在
console
内随意输入未知的脚本代码;- 开发时不要引用未知的可能包含恶意代码的脚本;
XSS
攻击避免方法(请阅读《Web 安全》系列书籍);- 全世界推进
Flash
的安全改善,使用HTML5
替代Flash
- ...