失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 浅谈Web身份识别技术 —— Cookie Session 和 Token

浅谈Web身份识别技术 —— Cookie Session 和 Token

时间:2021-11-29 09:07:34

相关推荐

浅谈Web身份识别技术 —— Cookie Session 和 Token

文章目录

1. 前言2. 过时的身份识别技术2.1 HTTP 首部2.2 客户端 IP2.3 用户登录2.4 胖 URL3. 常用的身份识别技术3.1 cookie3.2 session3.3 token4. 总结

1. 前言

由于 HTTP 协议是匿名的、无状态的协议,所以当服务端需要记录用户的状态时,就需要用某种机制来识别具体的用户。这也是一系列web身份识别技术如cookie、session 和 token 出现的原因。

在 HTTP 协议中,一共存在以下几种方式来实现:

承载用户身份信息的 HTTP 首部客户端 IP 地址跟踪,通过用户的 IP 地址对其进行识别用户登录,用认证方式来识别用户胖 URL,一种在 URL 中嵌入识别信息的技术cookie, 一种功能强大且高效的持久身份识别技术session,一种服务端存储的身份识别token, 一种无状态的身份识别技术

目前,前4种方式由于其存在的不足而几乎不再使用了,一般采用 session-cookie 或 token 或 token-session-cookie模式。

下面首先简单简述一下前4种,然后详细解析后面三种。

2. 过时的身份识别技术

2.1 HTTP 首部

From —— 包含用户的 Email 地址User-Agent —— 浏览器信息Referer —— 来源

From 首部包含了用户的E-mail地址。每个用户都有不同的E-mail地址,所以在理想情况下,可以将这个地址作为可行的源端来识别用户。但由于担心那些不讲武德的服务器会搜集这些E-mail,用于垃圾邮件的散发,所以很少有浏览器会发送From首部。实际上From首部一般由自动化的机器人或蜘蛛发送的,这样在出现问题时,网管还有个地方可以发送愤怒的投诉邮件。

User-Agent 首部可将用户所用浏览器的相关信息告知服务器,包括程序的名称和版本,通常还包含操作系统的相关信息。要实现定制内容与特定的浏览器及其属性间的良好互操作时,这个首部非常有用,但它并没有为识别特定的用户提供太多有意义的帮助。

Referer首部提共了用户来源页面的 URL。Referer 首部自身并不能完全识别用户,但它却是说明了用户之前访问过哪个页面。通过它可以更好地理解用户的浏览行为,以及用户的兴趣所在。比如,如果你是从一个篮球网站抵达某个Web服务器的,这个服务器可能会推断你是个篮球迷。

这三个首部都不足以实现可靠的识别。

2.2 客户端 IP

早期的Web先锋曾尝试将客户端 IP 地址作为一种标识行为使用,如果每个用户都有不同的 IP 地址,IP地址(如果会发生变化的话)也很少会发生变化,而且Web 服务器可以判断出每条请求的客户端 IP 地址的话这种方案是可行的。通常在HTTP 首部并不提供客户端的 IP 地址,但Web 服务器可以找到承载 HTTP请求的 TCP 连接另一端的 IP 地址。

但是,使用客户端 IP 地址来识别用户存在着很多缺点,限制了将其作为用户识别技术的效能。

客户端 IP 地址描述的是所用的机器,而不是用户。如果多个用户共享同一台机器,就无法对其进行区分了。很多因特网服务提供商都会在用户登录时动态为其动态分配 IP 地址。用户每次登录时,都会得到一个不同的地址,因此 Web 服务器不能假设 IP 地址可以在各登录会话之前标识用户。为了提高安全性,并对稀缺的地址资源进行管理,很多用户都是通过网络地址转换(NAT)防火墙来浏览网络请求的。这些 NAT 设备隐藏了防火墙后面那些实际客户端的 IP 地址,将实际的客户端 IP 地址转换成一个共享的防火墙 IP 地址(和不通过的端口号)。HTTP 代理和网关通常会打开一些新的、到原始服务器的 TCP 连接。 Web 服务器看到的将是代理服务器的 IP 地址,而不是客户端的。有些代理为了绕过这个问题会添加特殊的 Client-IP 或者 X-Forwarded-For 扩展首部来保存原始的 IP 地址。但并不是所有的代理都支持这种行为。

少数站点甚至将客户端 IP 地址作为一种安全特性使用,它们只向来自特定 IP 地址的用户提供文档。在内部网络中可能可以这么做,但在因特网上就不行了,主要是因为因特网上 IP 地址太容易被欺骗(伪造)了。

2.3 用户登录

Web 服务器无需被动地根据用户的 IP 地址来猜测他的身份,它可以要求用户通过用户名和密码进行认证(登录)来显示地询问用户是谁。

为了使 Web 站点的登录更加简便,HTTP 中包含了一种内建机制,可以用 www-Authenticate 首部和 Authorization 首部向 Web 站点传送用户的相关信息。一旦登录,浏览器就可以不断地在每条发往这个站点的请求中发送这个登录信息了,这样,就总是有登录信息可以用了。

其实这种方式跟之后出现的 cookie 在机制上十分类似,都是将用户名和密码添加在请求首部中,然后在每次请求中都向服务器发送Authorization首部作为一种身份的标识,也可以说是 cookie 的前身,但是这种方式存在很大的不足。

无法存储起来十分容易破解

之前我并未了解到还存在这种方式,是在《http权威指南》276页中学习到,但是其中并未给出这种方式明显的缺陷,上面两点是我总结而来。同时我并未完全想明白为何不完善这种方式而发展出 cookie。

2.4 胖 URL

所谓的胖 URL 也就是Web站点根据每个用户而给 URL 添加了一些额外的数据,服务器通过这些数据可识别用户身份。

举例来说www.arrow-?nameId=“paopao”, nameId 标识符为paopao,服务器可以用这个数据来识别客户端。

但是这种方式存在的不足十分明显:

丑陋的 URL

无法共享 URL

URL 中包含特定用户和会话有关的状态信息,如果将这个URL发送给其他人,可能就在无意中将个人信息共享出去了。

破坏缓存 —— 因为每个用户 URL 都不相同

服务器负担

非持久

但是,当浏览器不支持cookies时,自己又不想模拟cookie机制时,胖URL也是一种选择。

以上几种方式都存在对应的不足,因此几乎不会再使用了。

3. 常用的身份识别技术

3.1 cookie

在身份识别中,cookie 就好像服务器给用户贴的 “嗨,我叫”的贴纸一样,用户访问一个Web 站点时,这个 Web 站点就可以读取服务器贴在用户身上的所有贴纸。

用户首次访问Web站点时,通过用户名和密码向服务器发起登录请求,验证通过后,Web 服务器希望在这个用户下次回来的时候能识别出这个用户,就想着给这个用户“拍上”一个独有的cookie,这样以后他就可以识别这个用户了。cookie 中包含了一个由名字 = 值 (key=value)这样的信息构成的任意列表,并通过 Set-Cookie 或者 Set-Cookie2 HTTP响应(扩展)首部将其贴到用户身上去。大致过程如下图所示:

cookie中可以包含任意信息,但他们通常都只包含一个服务器为了进行跟踪而产生的独特的识别码,比如id=12345。服务器就可以通过这个数字来查找服务器为其访问者积累的数据库信息(购物历史,地址信息啥的)。

浏览器会记住从服务器返回的 Set-Cookie 或 Set-Cookie2 首部中的 cookie 内容,并将不同站点的 cookie分站点的存储在浏览器的cookie数据库中。

关于cookie的具体属性可到《HTTP权威指南》283页查看,包含了过期时间,域名,path,secure等。

cookie 还是存在一些不足的:

cookie无法承载较大数据,浏览器对cookie的数量和大小都存在不同的限制。同时访问时携带cookie也无形中增加了浏览器的流量。一般说来每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。安全性问题。如果cookie被人拦截了,那人就可以取得所有的信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。

cookie 存在这些问题,那么能不能想办法把会话状态保存在服务器呢?存储在服务器的话,就不再有了大小和数量的限制,因此就出现了 session 技术。

3.2 session

session 是一种将会话状态保存在服务器端的技术。可以比喻成是银行发放给客户的银行卡和银行为每个客户保留的账户档案的结合方式 。银行卡就相当于 session 技术中 服务端发给客户端的一个唯一标识,这个标识简单,唯一;银行为每个客户存储的账户档案就相当于 session 技术中服务器存储的会话状态(客户端唯一标识对应的信息,名字,性别,买了多少车等等)。

至于客户端怎么保存这个“身份标识”,可以有很多种方式。对于浏览器客户端,大家都默认采用 cookie 的方式,服务器给客户端发一个唯一的 sessionId。服务器使用 sessionId 把用户的信息临时保存在了服务器上,因此可以保存大量与此用户有关的信息,用户离开网站后 session 会被销毁(当然也可以设置长期保存 session,比如保存在文件,数据库等)。

这种用户信息存储方式相对 cookie 来说更安全,可是 session 有一个巨大的缺陷:

如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候,由于另一台服务器没有对应的session,会直接返回认证错误,进而需要用户重新登录。为了避免类似的问题,需要将 session 复制到所有的应用服务器,同时由于互联网的巨量用户必然会带来的海量 session 信息的存储需求,这对服务器存储能力是一个巨大的开销,而且严重限制了服务器的动态扩展能力(为了应对用户的巨量增长,互联网常用的做法是加服务器来保证服务能力的可用性),当然可以采用分布式缓存来对 session 信息进行集中存储,这又会带来新的问题,比如单点故障等。

因为上述问题的出现,那么能不能出现一种无状态的身份识别技术呢?如果无状态了,不仅不会出现负载的问题,也不会出现故障了。因此出现了一种 token 技术。

3.3 token

token即“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。在识别的机制上,token 和 session cookie是一样的,均是服务器颁发,客户端请求时携带,然后客户端验证识别。

token 的神奇之处(关键)在于它是如何实现无状态且实现防篡改的。

生成的 token 一般为三部分。

"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoidGVzdCIsImV4cCI6MTYwODUxMzc1MSwiaWF0IjoxNjA4NTEwMTUxfQ.UsTVoAx9glQRP-wIyuhK5yk1EB_d0Hx_-5YNnPwQ_9o"

# 第一部分 算法,类型{"alg":"HS256","typ":"JWT"}# 第二部分 数据,过期时间,生成时间{"data":"test","exp":1608513751,"iat":1608510151}

其中前两部分都是都是base64加密的,可以说是明文。

第三部分是签名,token 的关键就在于第三部分,签名是根据负载(传给客户端的数据)和密钥进行加密的(这里就以对称加密简述),这个签名和负载是一一对应的,而且是雪崩的,只要其中一个发生变化(篡改),那么另一个一定是雪崩式的。因此做到了防篡改。客户端把这个token在请求时发送给服务器,服务器根据负载和密钥同样进行加密签名,和客户端发送的签名进行校验便可验证身份。神奇呀!!

token具有以下好处。

token 完全由应用管理,所以它可以避开同源策略

token 可以很大程度避免 CSRF 攻击

token 可以是无状态的,可以在多个服务间共享。

但是token同样存在一些不足:

无法作废已经颁布的令牌

所有的认证信息都在 token 中,由于在服务端没有状态,即使你知道了某个 token 被盗取了,你也没有办法将其作废。在 token 过期之前(你绝对应该设置过期时间),你无能为力。

不能完全避免 CSRF 和 XSS 攻击

4. 总结

这里只是大致简述了目前存在的身份识别技术,并没有深度剖析。

关于cookie、session 和 token,没有哪一种是最好的,只有合适不合适,程序永远没有银弹。

如果觉得《浅谈Web身份识别技术 —— Cookie Session 和 Token》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。