@yangfch3
2015-12-05T10:01:54.000000Z
字数 4922
阅读 4785
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; HttpOnlySet-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- ...