web应用中的身份认证:cookie、session、token

lxf2023-08-01 00:40:01

 身份认证的三种方式

  • Cookie认证
  • session认证
  • token认证

Cookie

Cookie的工作原理

HTTP是一种无状态协议,服务器没有办法单单从网络连接上面知道访问者的身份,为了解决这个问题,就诞生了Cookie,Cookie实际上是一小段的文本信息,Cookies是由服务器产生的。

Cookie是一段不超过4KB的小型文本数据,由一个名称(Name)、一个值(Value)和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性组成。

浏览器第一次访问服务端时,服务器此时肯定不知道他的身份,所以创建一个独特的身份标识数据,格式为key=value,放入到Set-Cookie字段里,随着响应报文发给浏览器。浏览器看到有Set-Cookie字段以后就知道这是服务器给的身份标识,于是就保存起来,下次请求时会自动将此key=value值放入到Cookie字段中发给服务端。服务端收到请求报文后,发现Cookie字段中有值,就能根据此值识别用户的身份然后提供个性化的服务。相当于服务器给每个客户端都贴上了一个小纸条。上面记录了服务器给我们返回的一些信息。然后服务器再看到这张小纸条就知道我们是谁了。这就是Cookie的工作原理。

Cookie的结构

(1) Name/Value:设置Cookie的名称及相对应的值,对于认证Cookie,Value值包括Web服务器所提供的访问令牌 。

(2) Expires属性:设置Cookie的生存期。有两种存储类型的Cookie:会话性与持久性。Expires属性缺省时,为会话性Cookie,仅保存在客户端内存中,并在用户关闭浏览器时失效;持久性Cookie会保存在用户的硬盘中,直至生存期到或用户直接在网页中单击“注销”等按钮结束会话时才会失效。

(3) Path属性:定义了Web站点上可以访问该Cookie的目录 [3]  。

(4) Domain属性:指定了可以访问该 Cookie 的 Web 站点或域。Cookie 机制并未遵循严格的同源策略,允许一个子域可以设置或获取其父域的 Cookie。当需要实现单点登录方案时,Cookie 的上述特性非常有用,然而也增加了 Cookie受攻击的危险,比如攻击者可以借此发动会话定置攻击。因而,浏览器禁止在 属性中设置.org、.com 等通用顶级域名、以及在国家及地区顶级域下注册的二级域名,以减小攻击发生的范围。

(5) Secure属性:指定是否使用HTTPS安全协议发送Cookie。使用HTTPS安全协议,可以保护Cookie在浏览器和Web服务器间的传输过程中不被窃取和篡改。该方法也可用于Web站点的身份鉴别,即在HTTPS的连接建立阶段,浏览器会检查Web网站的SSL证书的有效性。但是基于兼容性的原因(比如有些网站使用自签署的证书)在检测到SSL证书无效时,浏览器并不会立即终止用户的连接请求,而是显示安全风险信息,用户仍可以选择继续访问该站点。由于许多用户缺乏安全意识,因而仍可能连接到Pharming攻击所伪造的网站。

(6) HTTPOnly 属性 :用于防止客户端脚本通过document.cookie属性访问Cookie,有助于保护Cookie不被跨站脚本攻击窃取或篡改。但是,HTTPOnly的应用仍存在局限性,一些浏览器可以阻止客户端脚本对Cookie的读操作,但允许写操作;此外大多数浏览器仍允许通过XMLHTTP对象读取HTTP响应中的Set-Cookie头。

Cookie的缺点

  • Cookie被附加在HTTP消息中,无形中增加了数据流量。
  • Cookie在HTTP消息中是明文传输的,所以安全性不高,容易被窃取。
  • Cookie存储于浏览器,可以被篡改,服务器接收后必须先验证数据的合法性。
  • 浏览器限制Cookie的数量和大小(通常限制为50 个,每个不超过4KB),对于复杂的存储需求来说是不够用的。

Session

Session的工作原理

浏览器第一次请求的时候,服务器里面会进行存储,生成一个session_id(唯一的,例如:uuid(universal unique identity)),然后通过cookie发送给浏览器。每次访问的浏览器不同的时候,服务器就会进行上面的操作,生成session_id并且发送给浏览器。当同一个浏览器去访问服务器的时候,由于之前存储过session_id,因此在登录的时候会把session_id一起发送给服务器,登录成功之后,就会把身份信息存储到对应的session_id下面。下次再登录,服务器发现这个session_id有对应的身份信息,即登录过,就不需要再次登录了。

工作原理:

1、创建session

当用户访问到一个服务器时,如果服务器启用Session,服务器就要为该用户创建一个Session,在创建这个Session的时候,服务器首先检查这个用户发来的请求里是否包含了一个Session_id,如果包含了一个Session_id,则说明了之前该用户已经登录过兵为此用户创建过session,那服务器就按照这个session_id把这个session在服务器的内存里找出来(如果找不到,就有可能为它新创建一个),如果客户端请求里不包含有session_id,则为该客户端创建一个session并生成一个与此session相关的session_id。

这个session id将在本次响应中返回到客户端保存,而保存这个session_id的正是cookie。

2、使用session

  • 将服务器返回的session_id保存在cookie里
  • 从cookie中取出session_id
  • url重写,将session_id附加在请求的url路径的后面

Session的缺点

  • 占用服务器资源:session的优点很多,但是它的缺点也是可以引起很大的问题的,可能极大地提高服务器成本。
  • 没有分布式架构,无法支持横向扩展:如果使用一个服务器,该模式完全没有问题。但是,如果它是服务器群集或面向服务的跨域体系结构的话,则需要一个统一的session数据库库来保存会话数据实现共享,这样负载均衡下的每个服务器才可以正确的验证用户身份。
  • session常用来文件存储的,性能不好
  • Session变量和cookies是同一类型的。如果某用户将浏览器设置为不兼容任何cookie,那么该用户就无法使用这个Session变量

Token

token的工作原理

token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。

当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。

Token的认证流程:

  • 用户输入用户名和密码,发送给服务器。
  • 服务器验证用户名和密码,正确的话就返回给客户端一个签名过的token。
  • 浏览器客户端拿到这个token,存储到cookie或者localStorage中。
  • 客户端后续每次请求中,会在 header中携带token发送给服务器。
  • 服务器器验证token并解析出用户ID等相关信息,通过调取数据库信息比对,如果有效那么认证就成功,可以返回客户端需要的数据,无效则返回错误信息引导客户端跳转到登陆页面

使用token的好处

  • 支持跨域访问
  • 无状态
  • 减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
  • 扩展性更强,也更安全点,能够隐藏真实的数据,非常适合用在 Web 应用或者移动应用上。
  • 适合用于微服务或者分布式。

token的缺点

1. 占带宽

正常情况下要比 session_id 更大,需要消耗更多流量,挤占更多带宽,假如你的网站每月有 10 万次的浏览器,就意味着要多开销几十兆的流量。听起来并不多,但日积月累也是不小一笔开销。实际上,许多人会在 JWT 中存储的信息会更多。

2. 无法在服务端注销,那么久很难解决劫持问题

3. 性能问题

JWT 的卖点之一就是加密签名,由于这个特性,接收方得以验证 JWT 是否有效且被信任。但是大多数 Web 身份认证应用中,JWT 都会被存储到 Cookie 中,这就是说你有了两个层面的签名。听着似乎很牛逼,但是没有任何优势,为此,你需要花费两倍的 CPU 开销来验证签名。对于有着严格性能要求的 Web 应用,这并不理想,尤其对于单线程环境。

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!