分享

web应用的session和token有什么联系?

 Fengsq501u81r4 2021-06-26

Http协议本身是一种无状态的协议,如果Http服务器需要浏览器提供用户名和密码来进行身份核验,那么浏览器每一次请求时,都需要做一次用户认证才行,因为Http服务器并不知道请求是哪个用户发出的。

为了让Http服务器识别出来是哪个用户发出的请求,需要在服务器存储一份用户登录的信息,这份登录信息会随着第一次请求的响应回传给浏览器。浏览器将其保存为cookie,以便下次请求时带上登录信息。这样下次请求时,服务器就能识别出请求来自哪个用户了。这就是传统的基于会话的认证。

基于server-session的认证流程

web应用的session和token有什么联系?

server-session流程图

(1)用户第一次访问时,服务器就会创建会话(session)对象,服务器为每一个session都分配一个唯一的sessionid,以保证每个用户都有不同的session对象。

(2)服务器在创建完session后,会把sessionid通过cookie返回给用户所在的浏览器,这样当用户再次发送请求时,通过cookie把sessionid传回服务器,服务器就能够根据sessionid找到与该用户对应的session对象。

session通常有失效时间的设定,当失效时间到了,服务器会销毁之前的session,并创建新的session返回给用户。但只要用户在失效时间内,有发送新的请求给服务器,通常服务器都会session的失效时间再延长。

(3)服务器获取用户的session对象后,看里面有没有登录成功的凭证,就能判断这个用户是否已经登录。当用户注销后,服务器会把session对象里的登录凭证清掉。

这种方式将会话信息存储在web服务器里面,在用户在线量比较多时,会占据较多的内存。另外当服务端应用采用集群部署的时候,多台服务器之间需要进行session共享。

通常的解决方案是采用redis缓存服务器来管理session,既可以减轻应用服务器的负担,又可以实现session共享。

除了在服务端管理会话信息,还可以将登录凭证保存在浏览器端。下面来看看基于浏览器cookie的认证流程。

基于cookie的认证流程

web应用的session和token有什么联系?

cookie-based认证流程

(1)用户发起登录请求,服务器验证用户名和密码等身份信息,如果验证通过,就为该用户创建一个登录凭证,最简单的凭证形式可以只包含:用户id、凭证创建时间和过期时间。

(2)服务器先对登录凭证进行数字签名,然后再用对称加密算法做加密处理,将加签加密的登录凭证(命名为ticket),写入cookie,再回传给浏览器。

添加数字签名的目的是防止登录凭证里的信息被篡改,一旦信息被篡改,那么服务器验签肯定会失败。加密的作用是防止cookie被截取后,泄露其中的用户信息。

(3)用户再次发起请求时,服务器通过登录凭证名称(ticket)获取到相关的cookie值。先做解密处理,再做验签。如果这两步成功,就可以拿到原始的登录凭证;如果这两步不成功,则不允许请求。

(4)服务器用这个凭证的过期时间和当前时间做对比,判断凭证是否过期。如果过期,就需要用户再重新登录;如果未过期,则允许请求继续。

这种方式最大的优点就是实现了服务端的无状态化,彻底移除了服务端对会话的管理的逻辑,服务端只需要负责创建和验证登录cookie即可,无需保持用户的状态信息。

如果服务端做了集群部署,只需要每个服务器的登录逻辑中加签验签和加密解密的代码一致,那么就可以在集群内实现会话共享。

但是server-session方案和cookie-based方案都要用到cookie,不适合native app里面使用,只适合浏览器。现在大部分互联网应用都是支持多端的,既要支持web端,也要支持app,就要考虑下面介绍的基于token的会话管理方式。

token-based会话管理

web应用的session和token有什么联系?

token-based会话管理流程与基于cookie的流程基本一致,只不过把ticket换成了token。在客户端获得token以后,再次请求时需要在http header或url参数中带上token。

token-based认证方式有以下特点:

  • 不需要依赖cookie,适用于app应用。当然这种方式也同样适用于web应用,token可以存在localStorage或者sessionStorage里面。每次发ajax请求的时候,都把token拿出来放到ajax请求的header里即可。

  • 在web应用里也存在跨域的问题。比如应用部署在a.com,api服务部署在b.com,从a.com里面发出ajax请求到b.com,会报跨域错误。这种问题可以用CORS(跨域资源共享)的方式来解决。

  • 存在token刷新的问题。很多场景都不希望每隔一段时间需要用户重新登录的情况出现。这个时候就得考虑token的自动刷新的问题,在token有效期过期前,通过程序逻辑自动刷新token。

总结

基于token的方案是实现会话管理的方案之一,但不是唯一的方案。目前应用最多的会话管理方案还是基于token的方案,不仅有很多实现,而且还有现成的标准可用,这个标准就是JWT(json-web-token)。在后面的文章中我们再来聊聊JWT标准。

参考资料:3种web会话管理的方式

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多