Cookie和session

1. 问题引入

1.1. 问题现象

在某些环境中,偶现登录系统后,从跳转后,无法正常进入页面,会自动跳转到登录页面。

1.2. 排查过程

  1. 搞清楚实现细节:经了解得知,整个登录流程为****跳转时,会在跳转链接上携带usertoken,进入运维系统后,会使用跳转链接上的相关信息调用登录接口;由于使用的是sword框架,登录成功的信息会采用Session进行存储。
  2. 复现问题,查看不同:尝试复现,并查找请求失败的接口,观察其不同的地方;经多次复现,发现请求时鉴权失败的接口的请求头中携带的Cookie信息并非是登录成功接口的响应头中要求设置的Cookie信息。查看浏览器控制面板中的Cookie信息,同样不是登录接口要求设置的Cookie,至此可以基本判断出是由于Cookie设置失败导致的自动跳转到了登录页面。
  3. 发现问题,查找根源:在上一步中知晓了是由于设置Cookie失败导致的问题,所以只需排查有设置Cookie行为的接口就行,故直接采用抓包软件抓取登录期间调用的所有接口,查看响应头中有Set-Cookie的接口。

抓包信息显示,共有三个接口会设置Cookie,并且其中一个接口是在登录接口发起后立即发起请求的,即与登录接口是并行发起的,且其响应头中的Set-Cookie的值与登录接口不同,是一个旧值。查看源代码,发现此接口确实是与登录接口并行发起的(查看还发现此接口调用的实际其实是不正确的)。

  1. 确认根源,模拟重现:经过上述的步骤,基本确定是由于接口发起时机不正确,导致了新Cookie被覆盖,由于两个接口是并行发起的,所以接口响应速度是偶然的,这也与此问题是偶现的能对应上。但为了准确,需要根据我们的猜想让问题100%复现,所以在sword的node层让出现问题的接口延迟返回,确保他永远比登录接口响应晚一点,如果问题原因与我们猜想的一致,那经此改造后问题应该会必现,经实际验证,修改后问题确实100%复现,到此问题原因已确认。

整个排查过程的宗旨就是:1. 异常现象与正常现象进行比对 ,查找不同点;2. 找到不同点后判断跟问题是否存在关系;3. 若存在关系,查看造成不同点的原因。

1.3. 问题原因

前端存在接口发起时机不正确,导致响应时可能会覆盖掉正确的登录接口设置的Cookie值,让后续请求的接口都是携带了一个错误的Cookie进行请求。

1.4. 解决方案

由于发起时机不正确的接口有设置Session,故响应头中必有Set-Cookie字段(原因可看2.4章节),所以只能修改接口的发起时机,确保其在登录完成后再发起请求(登录完成后发起请求,此接口就会在请求时携带正确的Cookie,这样响应时设置的Cookie也是正确的)。

2. 知识拓展

2.1. 历史起源

为什么会有Cookie和Session存在?一个东西的存在必然是为了解决某一个问题。Cookie和Session的存在其实就是为了解决同一个问题,这个问题就是:

HTTP连接的无状态特性。简单来说就是,每一次http请求都是独立的,前一次与后一次的请求并不会存在关联,也就是没有任何记忆的,虽然刚刚请求过一次,但下一次请求时服务器同样不知道你是谁。

上面说了是为了解决HTTP连接无状态的问题,那Cookie是如何解决的呢,简单来说使用了Cookie后整个通讯过程就是下列的这个图:

客户端首次访问服务器时,服务器会生成一些特殊信息(这些特殊信息其实就是Cookie),这些特殊信息通常都是文本方式。那这些信息是如何传递给客户端的呢?其实这些信息都是在响应头的Set-Cookie字段里,如下图的示例:

浏览器接收到请求响应后,如果响应头中有Set-Cookie字段,那么浏览器会自动将其存储起来。后续符合domain和path的请求中,都会在请求头中携带上这个信息。

通过这种方式,就可以使得HTTP请求中,携带了一些额外的信息,也就解决了无状态的问题。

由于数据都是存储在客户端的,所以Cookie是需要浏览器支持(或者未禁用Cookie)才行。

2.3. Session

Session的实现机制都Cookie稍有不同,但原理都是在请求的过程中附加一些信息,整个通讯流程如下图:

与Cookie不同,客户端在请求服务器后,服务器会将需要保存的状态信息存储在服务器上(可以是内存,或者数据库等),然后返回给客户端一个SessionId(通常采用Set-Cookie的方式,也就是需要Cookie支持)。

客户端拿到SessionId后,在后续的请求中携带此数据,这样服务器就能通过SessionId拿到对应的状态信息。

简单比对就是Cookie机制是检查"通行证"来确认身份,而Session机制是通过核对"客户明细表"来确认身份。

2.4. Koa-session

Koa-session是Koa的一个中间件,它在实现Session有点特殊,默认情况下,Session的数据不是存储在服务器上,而是将数据通过Set-Cookie的方式让客户端来存储。

但如果有指定存储的介质,比如采用内存来存储,koa-session的实现机制就与2.3章节中的机制一致,返回的是一个SessionId

2.5. 其他

  1. sword框架中,默认是采用的内存来存储Session。
  2. Cookie和Session的详细说明:
相关推荐
啧不应该啊4 小时前
vue配置axios
前端·javascript·vue.js
__fuys__4 小时前
【HTML样式】加载动画专题 每周更新
前端·javascript·html
yanlele4 小时前
前端面试第 66 期 - Vue 专题第二篇 - 2024.09.22 更新前端面试问题总结(20道题)
前端·javascript·面试
凌晨五点的星5 小时前
网络安全-webshell绕过,hash碰撞,webshell绕过原理
开发语言·前端·javascript
天心天地生5 小时前
【bugfix】-洽谈回填的图片消息无法显示
开发语言·前端·javascript
啧不应该啊5 小时前
element plus 按需导入vue
前端·javascript·vue.js
梅秃头6 小时前
vue2+elementUI实现handleSelectionChange批量删除-前后端
前端·javascript·elementui
请叫我欧皇i6 小时前
el-form动态标题和输入值,并且最后一个输入框不校验
前端·javascript·vue.js
忧郁的西红柿7 小时前
HTML-DOM模型
前端·javascript·html