转载自:https://harttle.land/2015/08/10/cookie-session.html

Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道。

因为HTTP协议是无状态的,即每次用户请求到达服务器时,HTTP服务器并不知道这个用户是谁、是否登录过等。现在的服务器之所以知道我们是否已经登录,

是因为服务器在登录时设置了浏览器的Cookie!Session则是借由Cookie而实现的更高层的服务器与浏览器之间的会话。

  

Cookie 的实现机制

Cookie是由客户端保存的小型文本文件,其内容为一系列的键值对。 Cookie是由HTTP服务器设置的,保存在浏览器中, 在用户访问该服务器的其他页面时,

会在HTTP请求中附上该服务器之前设置的Cookie

下面是Cookie的整个传递流程:

1、浏览器向某个URL发起HTTP请求(可以是任何请求,比如GET一个页面,POST一个登录表单等)

2、对应的服务器收到该HTTP请求,并计算应当返回给浏览器的HTTP响应(状态行,消息报头,空行、响应正文)

3、在响应头中加入Set-Cookie字段,它的值是要设置的Cookie。

4、浏览器收到来自服务器的HTTP响应

5、浏览器在响应头中发现Set-Cookie字段,就会将该字段的值保存在内存或者硬盘中,Set-Cookie字段的值可以是很多项Cookie,每一项都可以指定过期时间Expires。默认的过期时间是用户关闭浏览器时。

6、浏览器下次给该服务器发送HTTP请求时,会将服务器设置的Cookie附加在HTTP请求头字段Cookie中。浏览器可以存储多个域名下的Cookie,但只发送当前请求的域名曾经指定的Cookie,这个域名也可以在Set-Cookie字段中指定。

7、服务器收到这个HTTP请求,发现请求头中有Cookie字段,便知道之前就和这个用户打过交道了

8、过期的Cookie会被浏览器删除。

总之,服务器通过Set-Cookie响应头字段来指示浏览器保存Cookie,浏览器通过Cookie请求头字段来告诉服务器之前的状态。Cookie中包含若干个键值对,每个键值对都可以单独设置过期时间。

Cookie 的安全隐患

Cookie提供了一种手段可以使得HTTP请求可以附加当前状态,现今的网站也是靠Cookie来标识用户的登录状态的:

1、用户提交用户名和密码的表单,这通常是一个POST HTTP请求

2、服务器验证用户名和密码,如果合法则返回200(OK),并设置Set-Cookie为authed=true。

3、浏览器存储该Cookie

4、浏览器发送请求时,在请求头中设置Cookie字段为authed=true。

5、服务器收到第二次请求,从Cookie字段得知该用户已经登录。按照已经登录用户的权限来处理此次请求。

但是,有个严重的问题:

发送HTTP请求的不只是浏览器,很多HTTP客户端软件(curl、Node.js)都可以发送任意的HTTP请求,可以设置任何头字段。假如我们直接设置Cookie字段为authed=true并发送该HTTP请求,服务器岂不是被欺骗了?这种攻击非常容易,Cookie是可以被篡改的。

Cookie 防篡改机制

服务器可以为每个Cookie项生成签名,由于用户篡改Cookie后无法生成对应的签名,服务器便可以得知用户对Cookie进行了篡改。一个简单的校验过程如下:

1、在服务器中配置一个不为人知的字符串(我们叫它Secret),比如:想x%#4

2、当服务器需要设置Cookie时(比如authed=false),不仅设置authed的值为false。在值的后面进一步设置一个签名,最终设置的Cookie是authed=false|djdjjddlleeke

3、签名 djdjjddlleeke 是这样生成的:hash('x%#4'+'false')。要设置的值与Secret想加再取哈希

4、用户收到HTTP响应并发现头字段set-Cookie:authed=false|djdjjddlleeke

5、用户在发送HTTP请求时,发现Cookie:authed=true|???。服务器开始进行校验:Hash('x%#4'+'true''),便会发现用户提供的签名不正确。通过给Cookie签名,使得服务器得以知道Cookie被篡改。然而,因为Cookie是明文传输的,只要服务器设置过一次authed=true|xxx,用户就知道true的签名是xxx了,以后就可以用这个签名在没有登录的情况下来欺骗服务器了。因此Cookie中最好不要放敏感数据。一般来讲Cookie中只放一个SessionId,而Session存储在服务器端。

Session 的实现机制

Session是存储在服务端的,避免了在客户端Cookie中存储敏感数据。Session可以存储在HTTP服务器的内存中,也可以存在内存数据库如redis中,对于重量级的应用甚至可以存储在数据库中。

以存储在redis中的Session为例,考察如何验证用户登录状态的问题:

1、用户提交包含用户名和密码的表单,发送HTTP请求。

2、服务器验证用户发来的用户名和密码

3、如果正确则 把当前用户名(通常是用户对象)存储到redis中,并生成它在redis中的key(ID),这个ID称为SessionID,通过SessionID可以从redis中取出对应的用户对象,敏感数据(比如authId=true)都存储在这个用户对象中。

4、设置Cookie为SessionId=xxxx|checksum并发送HTTP响应,仍然为每一项Cookie都设置签名

5、用户收到HTTP响应后,便看不到任何敏感数据了。在此后的请求中发送该Cookie给服务器。

6、服务器收到此后的HTTP请求后,发现Cookie中有SessionID,进行防篡改验证

7、防篡改验证通过后,根据ID从Redis中取出对应的用户对象,查看该对象的状态并继续执行业务逻辑

Web应用框架都会实现上述过程,在Web应用中可以直接获得当前用户。相当于在HTTP协议之上,通过Cookie实现了持久的会话。这个会话便称为Session。

Cookie/Session的机制与安全的更多相关文章

  1. [转载]Cookie/Session的机制与安全

    Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道.本文来详细讨论Cookie和Session的实现机制,以及其中涉及的安全问题. 因 ...

  2. Cookie/Session的机制

    Cookie的机制 Cookie是浏览器(User Agent)访问一些网站后,这些网站存放在客户端的一组数据,用于使网站等跟踪用户,实现用户自定义功能. Cookie的Domain和Path属性标识 ...

  3. [06] Session实现机制以及和Cookie的区别

    1.为什么有Session和Cookie 根据早期的HTTP协议,每次request-reponse时,都要重新建立TCP连接.TCP连接每次都重新建立,所以服务器无法知道上次请求和本次请求是否来自于 ...

  4. 【转】Cookie/Session机制详解

    Cookie/Session机制详解   会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息 ...

  5. Chrome的cookie放在哪里了,Cookie/Session机制详解

    Chrome的cookie放在哪里了,Cookie/Session机制详解:https://blog.csdn.net/u010002184/article/details/82082951

  6. 第十一篇 session和cookie自动登录机制

    session和cookie的作用和区别可以在网上查到,这里简单说下,我们使用的http协议本身是种无状态的协议,就是说web服务器接收到浏览器的请求,会直接返回相应内容,并不会检查是哪个浏览器,即浏 ...

  7. cookie,session,sessionid

    cookie,session,sessionid http协议是无状态的,意思是每次请求的状态不会保存.因此,产生了cookie,session之类保存会话状态的机制.1.什么是cookiecooki ...

  8. atitit. access token是什么??微信平台公众号开发access_token and Web session保持状态机制

    atitit. access token是什么??微信平台公众号开发access_token and Web session保持状态机制 1. token机制and  session保持状态机制 1 ...

  9. Web安全测试学习笔记(Cookie&Session)

    一,Session:含义:有始有终的一系列动作\消息1, 隐含了“面向连接” 和“保持状态”两种含义2, 一种用来在客户端与服务器之间保持状态的解决方案3, 也指这种解决方案的存储结构“把××保存在s ...

随机推荐

  1. WPF中触发器Trigger、MultiTrigger、DataTrigger、MultiDataTrigger、EventTrigger几种

    WPF中有种叫做触发器的东西(记住不是数据库的trigger哦).它的主要作用是根据trigger的不同条件来自动更改外观属性,或者执行动画等操作. WPFtrigger的主要类型有:Trigger. ...

  2. 利用ApplicationContextAware装配Bean

    @Component public class SpringUtil implements ApplicationContextAware { private static ApplicationCo ...

  3. 使用 RAII 完成线程等待

    当使用 std::thread 对象执行线程时,必须要调用 join() (或者 detach(),由于 detach() 可以立即调用,所以这里只考虑 join()) #include <io ...

  4. 一起学爬虫——通过爬取豆瓣电影top250学习requests库的使用

    学习一门技术最快的方式是做项目,在做项目的过程中对相关的技术查漏补缺. 本文通过爬取豆瓣top250电影学习python requests的使用. 1.准备工作 在pycharm中安装request库 ...

  5. Expression Trees 参数简化查询

    ASP.NET MVC 引入了 ModelBinder 技术,让我们可以在 Action 中以强类型参数的形式接收 Request 中的数据,极大的方便了我们的编程,提高了生产力.在查询 Action ...

  6. Codeforces 750E New Year and Old Subsequence 线段树 + dp (看题解)

    New Year and Old Subsequence 第一感觉是离线之后分治求dp, 但是感觉如果要把左边的dp值和右边的dp值合起来, 感觉很麻烦而且时间复杂度不怎么对.. 然后就gun取看题解 ...

  7. redis学习(八)——redis应用场景

    毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作,为不同的大象 ...

  8. vue v-cloak知识点

    1.使用 v-cloak 属性可以解决插值表达式闪烁问题;     2.v-text默认是没有闪烁的问题,同时会覆盖元素中原本的内容,但是v-cloak只会替换 自己的这个占位符,不会替换所有的字符 ...

  9. JavaScript之扑朔迷离的this

    JavaScript这门语言中,最令人迷惑的地方有三个,闭包.this.原型.针对大多数人,可以利用词法作用域等避开this的坑,但是我们不能一直生活在舒适区,要敢于打破砂锅问到底,对我们来说也是一种 ...

  10. Fliptile [POJ3279] [开关问题]

    题意 给定一张n*m的方格图,有1,0两种数字,每次可以选取一个十字进行翻转,1变成0,0变成1,问最少需要翻转几次,使它全部变成0,全部如果有重复的,按字典序最小的进行输出: 输入 第一行n,m 下 ...