[ web基础篇 ] session,cookie,token 那些事儿 ?

简介: session ?cookie ?token ?相信大家对这几个词并不陌生,不管是面试还是工作都会有涉及的,可想而知它的重要性。网上关于 session、cookie、token 的文章有很多,每篇文章都有一些独特的见解。在写文章之前,我看了很多篇 session、cookie、token 的文章,感觉很多都没有讲的很清楚,泛泛而谈。在看了这么多的文章之后,我对这几次词又有了不一样的理解,在这里和大家分享一下。

🍬 博主介绍


👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~

✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】

🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋

🎉欢迎关注💗一起学习👍一起讨论⭐一起进步📝文末有彩蛋

🙏作者水平有限,欢迎各位大佬指点,相互学习进步!


一、聊一下发展史



1.第一阶段:请求+响应


在很久以前,Web基本上就是文档的浏览而已,服务器不需要记录谁在某一段时间里都浏览了什么文档,每次请求都是一个新的HTTP请求,都会建立有一个新的连接。

就是请求加响应,不需要记住谁刚刚发了HTTP请求,每个请求对服务器来说都是全新的。


2.第二阶段:请求+下发会话标识+响应


随着交互式Web应用的兴起,像在线购物网站,需要登录的网站等等,马上就面临一个问题,那就是要管理会话,必须记住哪些人登录系统,哪些人往自己的购物车中放商品,也就是说服务器必须把每个用户分开。

然而,这是个不小的挑战,因为HTTP请求是无状态的,所以想出的办法就是给大家发一个会话标识( session id ),说白了就是一个随机的字串,每个人收到的都不一样,每次大家向浏览器发起HTTP请求的时候,把这个字符串给一并捎过来, 这样就能区分开来了。


1. http是一个无状态协议

什么是无状态呢?

就是说这一次请求和上一次请求是没有任何关系的,互不认识的,没有关联的。

这种无状态的的好处是快速。

坏处是假如我们想要把www.zhihu.com/login.htmlwww.zhihu.com/index.html关联起来,必须使用某些手段和工具。


3.第三阶段:请求+请求会话标识+响应

每个用户只需要保存自己的 session id,而服务器要保存所有人的 session id,这样的话,服务器的压力就大了。

如果说,访问服务器的用户很多很多,那么,服务器可能就需要存储成千上万,甚至几十万个 session id

这对服务器说是一个巨大的开销, 严重的限制了服务器扩展能力。


1.解释一下这里的服务器拓展能力

比如说我用两个机器组成了一个集群,小 F 通过机器 A 登录了系统,那session id会保存在机器 A 上,机器B可没有小F session id,假设小F的下一次请求被转发到机器B怎么办呢?

可能会采用一点小伎俩: session sticky

就是让小F的请求一 直粘连在机器A上,但是这也不管用,要是机器A挂掉了 ,还得转到机器B去。

那只好做session的复制了,把session id在两个机器之间搬来搬去,很麻烦。

image.png


2.集中session

后来有个叫Memcached的人提出:把session id集中存储到一个地方,所有的机器都来访问这个地方的数据。

这样一来,就不用复制了,但是增加了单点失败的可能性,要是那个负责session的机器挂了,所有人都得重新登录一遍,这无疑是一个很大的问题。

image.png


4.第四阶段:token代替session

于是有人提出:能不能只让每个客户端去保存自己的 session 而服务器不需要保存呢 ?

可是问题来了:如果不保存这些 session id,怎么验证客户端发给服务器 session id 的确是服务器生成的呢?

如果不去验证, 服务器都不知道他们是不是合法登录的用户,那黑客们就可以伪造 session id ,为所欲为了。

有了上面的讨论,我们可以想到一个关键点:验证


1. 签名完成token验证

比如说,小F已经登录 了系统,服务器给他发一个令牌,这个令牌就是token, 里边包含了小F user id,下一 次小 F 再次通过 Http 请求访问服务器的时候,把这个 token 通过 Http header 带过来不就可以了。

其实这样和 session id 没有本质区别,任何人都可以可以伪造。

又有人提出:录用签名来防止伪造。


2. 签名形成过程:

比如说服务器用HMAC-SHA256 算法,加上一个只有服务器才知道的密钥,对数据做一个签名,把这个签名和数据一起作为 token,由于密钥别人不知道, 就无法伪造token了 。

image.png


3.签名验证token过程:

这个token服务器不保存,当小F把这个token 给服务器发过来的时候,我再同样的 HMAC-SHA256 算法和同样的密钥,对数据再计算一次签名,和 token 中的签名做个比较。

如果相同, 我就知道小F已经登录过了 ,并且可以直接取到小Fuser id,如果不相同,数据
部分肯定被人篡改过,我就告诉发送者: 对不起, 没有认证。


image.png


这样一来,服务器就不保存 sessionid 了,只是生成 token ,然后验证 token ,服务器的 CPU 计算时间获取了我的session存储空间。

解除了 session id这个负担,服务器的机器集群就可以可以轻松地做水平扩展,用户访问量增大, 直接加机器就行。


4. cookie

服务器就要给每个客户端分配不同的 token,然后客户端每次向服务器发请求的时候,都带上这个 token,服务器就知道这个请求来自于谁了。

至于客户端怎么保存这个 token,可以有很多种方式,对于浏览器客户端,大家都默认采用cookie的方式。


5.注意点:

Token中的数据是明文保存的(虽然服务器会用Base64做下编码,但那不是加密) ,还是可以被别人看到的, 所以服务器不能在其中保存像密码这样的敏感信息。

如果谋和用户的 token 被盗,那服务器也没办法 ,服务器只认 token ,也就是说会认为小偷就是合法用户,这其实和用户的 session id 被盗是一样的。


5.总结:

介绍完了发展史相信你对 sessioncookietoken有了一定的认证。

接下来具体再介绍一下这三者。


二、Cookie



1.什么是Cookie

Cookie 技术产生源于 HTTP 协议在互联网上的急速发展。

随着互联网时代的发展,带宽等限制不存在了,人们需要更复杂的互联网交互活动,就必须同服务器保持活动状态(保活)


于是,在浏览器发展初期,为了适应用户的需求技术上推出了各种保持 Web 浏览状态的手段,其中就包括了 Cookie 技术。


Cookie 在计算机中是个存储在浏览器目录中的文本文件,当浏览器运行时,存储在 RAM 中发挥作用 (此种 Cookies 称作 Session Cookies),一旦用户从该网站或服务器退出,Cookie 可存储在用户本地的硬盘上 (此种 Cookies 称作 Persistent Cookies)。


cookie 由服务器生成,发送给浏览器,浏览器把 cookie keyvalue 形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该 cookie 发送给服务器。

由于 cookie 是存在客户端上的,所以浏览器加入了一些限制确保 cookie 不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的 cookie 数量是有限的。


2. Cookie 起源

1993 年,网景公司雇员 Lou Montulli 为了让用户在访问某网站时,进一步提高访问速度,同时也为了进一步实现个人化网络,发明了今天广泛使用的 Cookie


3. Cookie时效性

目前有些 Cookie 是临时的,有些则是持续的。临时的 Cookie 只在浏览器上保存一段规定的时间,一旦超过规定的时间,该 Cookie 就会被系统清除。


4. Cookie使用限制

Cookie 必须在 HTML 文件的内容输出之前设置;不同的浏览器对 Cookie 的处理不一致,使用时一定要考虑;客户端用户如果设置禁止 Cookie,则 Cookie 不能建立。

并且在客户端,一个浏览器能创建的 Cookie 数量最多为 300 个,并且每个不能超过 4KB,每个 Web 站点能设置的Cookie 总数不能超过 20 个。


5.执行流程:


1. HTTP Request

首先,客户端会发送一个http请求到服务器端。


2. HTTP Response + Set-Cookie

服务器端接受客户端请求后,建立一个session,发送一个http响应到客户端,这个响应头,其中就包含Set-Cookie头部,该头部包含了session id

Set-Cookie格式:
Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]


3. HTTP Response + Cookie

在客户端发起的第二次请求提供给了服务器端可以用来唯一标识客户端身份的信息。

(注意:如果服务器需要我们带上Cookie,我们就需要在B步骤上面拿到这个Cookie然后作为请求头一起发起第二次请求),

这时,服务器端也就可以判断客户端是否启用了cookies

尽管,用户可能在和应用程序交互的过程中突然禁用cookies的使用,但是,这个情况基本是不太可能发生的,所以可以不加以考虑,这在实践中也被证明是对的。


4. HTTP Response

4. 浏览器返回请求内容

为了方便理解,可以先看下这张流程执行图加深概念:

image.png


6.浏览器中cookie所在位置

image.png

 

三、Session



session从字面上讲,就是会话。

这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?

对方肯定有某种特征(如长相)表明他就是张三。


session也是类似的道理,服务器要知道当前发请求给自己的是谁。

为了做这种区分,服务器就要给每个客户端分配不同的"身份标识",然后客户端每次向服务器发请求的时候,都带上这个,服务器就知道这个请求来自于谁了。

至于客户端怎么保存这个"身份标识",可以有很多种方式,对于浏览器客户端,大家都默认采用cookie的方式。


服务器使用session把用户的信息临时保存在了服务器上,户离开网站后session会被销毁。


这种用户信息存储方式相对cookie来说更安全。

Session是对于服务端来说的,客户端是没有Session一说的。

Session是服务器在和客户端建立连接时添加客户端连接标志,最终会在服务器软件(ApacheTomcatJBoss)转化为一个临时Cookie发送给给客户端,当客户端第一请求时服务器会检查是否携带了这个Session(临时Cookie),如果没有则会添加Session,如果有就拿出这个Session来做相关操作。


可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。


举例:

用户在www.a.com/login.php里面登陆了,用户在www.a.com/index.php也希望是登陆状态,但是,这是2个不同的页面,也就是2个不同的HTTP请求,这2HTTP请求是无状态的,也就是无关联的,所以无法单纯的在index.php中读取到它在login.php中已经登陆了,需要重新登陆。


四、Token



1.什么是token


1.简介

token 也称作令牌,由uid+time+sign[+固定参数]

token 的认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式,非常适合于 REST API 的场景。

所谓无状态就是服务端并不会保存身份认证相关的数据。

Web领域基于Token的身份验证随处可见。

在大多数使用Web API的互联网公司中,tokens 多户下处理认证的最佳方式。

例如:Facebook, Twitter, Google+, GitHubAPIWeb应用都使用tokens


2.组成

uid: 用户唯一身份标识

time: 当前时间的时间戳

sign: 签名, 使用 hash/encrypt 压缩成定长的十六进制字符串,以防止第三方恶意拼接

固定参数(可选): 将一些常用的固定参数加入到token 中是为了避免重复查库


3.存放

token在客户端一般存放于localStoragecookie,或sessionStorage中。在服务器一般存于数据库中


2.基于Token的身份验证的优势:

无状态、可扩展、支持移动设备、跨程序调用、 安全


1.无状态

在客户端存储的Tokens是无状态的,并且能够被扩展。

基于这种无状态和不存储Session信 息,负载负载均衡器能够将用户信息从一个服务传到其他服务器上。

如果我们将已验证的用户的信息保存在Session中,则每次请求都需要用户向已验证的服务器发送验证信息(称为Session亲和性)

用户量大时,可能会造成一些拥堵。但是不要着急。

使用tokens之 后这些问题都迎刃而解,因为tokens自 己hold住了户的验证信息。


2.安全性

请求中发送token而不再:是发送cookie能够防止CSRF(跨站请求伪造)

即使在客户端使用cookie存储token, cookie也仅仅是一 个存储机制而不是用于认证。

不将信息存储在Session中,让我们少了对session操作。

token是有时效的,一段时间之后用户需要重新验证。

我们也不一定需要等到token自动失效,token有 撤回的操作,通过token revocataion可以使-个特定的token或是一-组有 相同认证的token无效。


3.可扩展性

Tokens能够创建与其它程序共享权限的程序。例如,能将一个随便的社交帐号和自己的大号(Fackbook或是Twitter)联系起来。

当通过服务登录Twittr(我们将这个过程Buffer)时,我们可以将这些Buffer附到Twitter的数据流上(we are allowing Buffer to post to our Twitter stream)

使用tokens时,可以提供可选的权限给第三方应用程序。当用户想让另一个应用程序访问它们的数据,我们可以通过建立自己的API,得出特殊权限的tokens


4.多平台跨域

开启CORS(跨域资源共享),对应用程序和服务进行扩展的时候,需要介入各种各种的设备和应用程序。

只要用户有一个通过了验证的token,数据和资源就能够在任何域上被请求到。


3.基于服务器验证方式暴露的一些问题

1. Seesion 每次认证用户发起请求时,服务器需要去创建一个记录来存储信息。 当越来越多的用户发请求时,内存的开销也会不断增。

2. 可扩展性:在服务端的内存中使用Seesion存储登录信息,伴随而来的是可扩展性问题。

3. CORS(跨域资源共享):当我们需要让数据跨多台移动设备上使用时,跨域资源的共享会是一个让人头疼的问题。在使用Ajax抓取另一个域的资源,就可以会出现禁止请求的情况。

4. CSRF(跨站请求伪造):用户在访问银行网站时,他们很容易受到跨站请求伪造的攻击,并且能够被利用其访问其他的网站。

在这些问题中,可扩展行是最突出的。因此我们有必要去寻求一种更有行之有效的方法。


4.基于Token的验证原理

基于Token的身份验证是无状态的,我们不将用户信息存在服务器或Session中。

这种概念解决了在服务端存储信息时的许多问题。

NoSession意味着你的程序可以根据需要去增减机器,而不用去担心用户是否登录。


1.基于Token的身份验证的过程如下:

1.用户通过用户名和密码发送请求。

2.程序验证。

3.程序返回一个签名的token给客户端。

4.客户端储存token,并且每次用于每次发送请求。

5.服务端验证token并返回数据。

每一次请求都需要tokentoken应该在HTTP的头部发送从而保证了Http请求无状态。

我们同样通过设置服务器属性 Access-Control-Allow-Origin:*,让服务器能接受到来自所有域的请求。

需要主要的是,在ACAO头部标明(designating)*时, 不得带有像HTTP认证,客户端SSL证书和cookies的证书。


2.实现思路:

image.png


1.用户登录校验,校验成功后就返回Token给客户端。

2.客户端收到数据后保存在客户端

3.客户端每次访问API是携带Token到服务器端。

4.服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码。

当我们在程序中认证了信息并取得token之后,我们便能通过这个Token做许多的事情。

我们甚至能基于创建一个基 于权限的token传给第三方应用程序,这些第三方程序能够获取到我们的数据( 当然只有在我们允许的特定的token)


3.注意:

cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中。

现在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理论上都可以保持会话状态。可是实际中因为多种原因,一般不会单独使用。

session只需要在客户端保存一个id,实际上大量数据都是保存在服务端。如果全部用cookie,数据量大的时候客户端是没有那么多空间的。

如果只用cookie不用session,那么账户信息全部保存在客户端,一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大。


4.总结:

简而言之, session 有如用户信息档案表, 里面包含了用户的认证信息和登录状态等信息. cookie 就是用户通行证


五、CookieSession的区别:



1. 数据存放位置不同:Session数据是存在服务器中的,cookie数据存放在浏览器当中。

2. 安全程度不同:cookie放在服务器中不是很安全,session放在服务器中,相对安全。

3. 性能使用程度不同:session放在服务器上,访问增多会占用服务器的性能;考虑到减轻服务器性能方面,应使用cookie

4. 数据存储大小不同:单个cookie保存的数据不能超过4Ksession存储在服务端,根据服务器大小来定。


六、Token Session 的区别:


1. token是开发定义的,sessionhttp协议规定的;

2. token不一定存储,session存在服务器中;

3. token可以跨域,session不可以跨域,它是与域名绑定的。


七、token可以抵抗csrfcookie+session不行


关于什么是CSRF可以看常见web漏洞总结------CSRF

假如用户正在登陆银行网页,同时登陆了攻击者的网页,并且银行网页未对csrf攻击进行防护。

攻击者就可以在网页放一个表单,该表单提交srchttp://www.bank.com/api/transferbodycount=1000&to=Tom

倘若是 session+cookie,用户打开网页的时候就已经转给Tom1000元了。

因为 form 发起的 POST 请求并不受到浏览器同源策略的限制,因此可以任意地使用其他域的 Cookie 向其他域发送 POST 请求,形成 CSRF 攻击。

post 请求的瞬间,cookie 会被浏览器自动添加到请求头中。

token不同,token 是开发者为了防范 csrf 而特别设计的令牌,浏览器不会自动添加到headers 里,攻击者也无法访问用户的 token,所以提交的表单无法通过服务器过滤,也就无法形成攻击。


八、总结


session 存储于服务器,可以理解为一个状态列表,拥有一个唯一识别符号 session id,通常存放于 cookie 中。服务器收到 cookie 后解析出 session id,再去 session 列表中查找,才能找到相应 session,依赖 cookie


cookie类似一个令牌,装有sessionId,存储在客户端,浏览器通常会自动添加。

token 也类似一个令牌,无状态,用户信息都被加密到token中,服务器收到token后解密就可知道是哪个用户。需要开发者手动添加。


写在最后:


sessioncookietoken 其实理解起来不难,就是有点绕。

搞明白了 web 发展的一个历程,理解一下各自原理,区别其实就差不多了。

当然,我是身处安全岗,也是站在安全岗的定位来看的,对于研发岗可能有不一样的深度。


至此,本文基本完成,历时20小时,在这短时间里,自己也收获很多,同时希望能助人理解sessioncookietoken

本文,参考了很多文章,在此申明。

参考文章:
Token(计算机术语)_百度百科 (baidu.com)

                 session(计算机术语)_百度百科 (baidu.com)

                 cookie(储存在用户本地终端上的数据)_百度百科 (baidu.com)

                 有了cookie为什么需要session - SegmentFault 思否

                 sessioncookietoken的区别 - 知乎 (zhihu.com)

                 token优势步骤实现_自己对幸福的要求是什么的博客-CSDN博客

                 彻底弄懂sessioncookietoken - SegmentFault 思否

                 CookieSessionToken那点事儿(原创) - 简书 (jianshu.com)

                 彻底理解cookiesessiontoken - 墨颜丶 - 博客园 (cnblogs.com)

                 cookie, session, token 发展史 - 天军 - 博客园 (cnblogs.com)

                 CookieSessionToken - 掘金 (juejin.cn)

相关文章
|
1月前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
61 4
|
3月前
|
存储 安全 NoSQL
Cookie、Session、Token 解析
Cookie、Session、Token 解析
65 0
|
4月前
|
存储 安全 搜索推荐
【JavaWeb 秘籍】Cookie vs Session:揭秘 Web 会话管理的奥秘与实战指南!
【8月更文挑战第24天】本文以问答形式深入探讨了Web开发中关键的会话管理技术——Cookie与Session。首先解释了两者的基本概念及工作原理,随后对比分析了它们在存储位置、安全性及容量上的差异。接着,通过示例代码详细介绍了如何在JavaWeb环境中实现Cookie与Session的操作,包括创建与读取过程。最后,针对不同应用场景提供了选择使用Cookie或Session的指导建议,并提出了保障二者安全性的措施。阅读本文可帮助开发者更好地理解并应用这两种技术。
76 1
|
4月前
|
C# 开发者 Windows
WPF遇上Office:一场关于Word与Excel自动化操作的技术盛宴,从环境搭建到代码实战,看WPF如何玩转文档处理的那些事儿
【8月更文挑战第31天】Windows Presentation Foundation (WPF) 是 .NET Framework 的重要组件,以其强大的图形界面和灵活的数据绑定功能著称。本文通过具体示例代码,介绍如何在 WPF 应用中实现 Word 和 Excel 文档的自动化操作,包括文档的读取、编辑和保存等。首先创建 WPF 项目并设计用户界面,然后在 `MainWindow.xaml.cs` 中编写逻辑代码,利用 `Microsoft.Office.Interop` 命名空间实现 Office 文档的自动化处理。文章还提供了注意事项,帮助开发者避免常见问题。
290 0
|
4月前
|
JSON Java API
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
105 0
|
4月前
|
前端开发 JavaScript
【Azure 环境】前端Web通过Azure AD获取Token时发生跨域问题(CORS Error)
【Azure 环境】前端Web通过Azure AD获取Token时发生跨域问题(CORS Error)
|
4月前
|
API
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
|
1月前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
2月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
191 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
2月前
|
存储 安全 数据安全/隐私保护
Cookie 和 Session 的区别及使用 Session 进行身份验证的方法
【10月更文挑战第12天】总之,Cookie 和 Session 各有特点,在不同的场景中发挥着不同的作用。使用 Session 进行身份验证是常见的做法,通过合理的设计和管理,可以确保用户身份的安全和可靠验证。
26 1