一文讲清楚什么是服务器Session、浏览器SessionStorage和Cookie

最近作者在学习nest框架,在前端验证码实战中遇到了一些问题。为什么服务器端设置的session会保存到浏览器的cookie里?服务器端又是否会保存session数据呢?在经过大量的资料查询后,就有了这篇文章: 作者旨在用通俗易懂的语言,讲清楚什么是服务器session、浏览器的sesisonStorage和Cookies

服务器Session

简单来说,Session是服务器端存储数据的一种方式。

首先我们要区分Session和SessionStorage,这两个概念在作者初学时经常搞混,在这里我们只需要记住一句话:

Session里的数据存储到服务器端,SessionStorage里的数据存储到用户本地浏览器

如果你和作者一样,是学前端的,那么你可能会产生和作者一样的感叹:原来服务器端也能保存数据啊!在很长一段时间里,作者都以为服务器端的数据都会通过HTTP协议,存储到本地浏览器里。当时还在想,在做前端登录验证码的时候,如果在浏览器储存中找到验证码图片对应的值直接填进去,不就可以绕过验证码?

常见的登录验证码图片:

事实证明还是作者太年轻。

为什么需要Session?

回到文章,既然Session的数据存在服务器端,那为什么需要Session呢?如果要做验证码的话,需要有个地方保存验证码图片对应的值,即文本"9HZ1" ,然后前端收集到用户输入的验证码后做验证。如果这个文本值存在浏览器本地的话,那就非常容易绕过去,只需要找到存储的地方,找到对应的值就好了。

所以为了安全性,服务器端需要能够存储数据的地方,这个地方就是Session

那么除了这个用途外呢?Session还可以用来做什么呢?在深入了解这个问题前,我们先来看看Session的存储格式:

Session存储格式

Session里的数据是通过键值对的形式储存的,你可以将Session看作许多个小格子,每一个小格子都可以存储独立的数据。每一个小格子都有需要设置一个独一无二的ID,即session_id,用来标识数据,通常这个session_id是随机生成的,你也可以自定义。我们可以用一个小格子,对应一个登陆的用户:

js 复制代码
{
  "session_id": "独一无二的ID,用来标识Session",
  //存入用户id
  "user_id": 42,
  //如果用户没有登录,则为false
  "is_authenticated": true,
  //假设我们做的是电商平台,这里可以存入用户购物车的数据
  "shopping_cart": [
    {"item_id": 101, "quantity": 2},
    {"item_id": 205, "quantity": 1}
  ]
}

不知道你有没有注意到,我们在Session里面存入了用户的数据,其中有一点就是用户是否登录。要知道HTTP协议是无状态的,用户登陆前发送的Post请求和登陆后发送的Post请求没有区别。

那我们如何分辨,哪些请求是登陆前发送的,哪些请求是登陆后发送的呢?我们就可以用Sessioin来解决,通过在Session中保存用户登录状态,然后收到用户Post请求后,查询服务器本地的Session,找到用户id为42对应的Session,然后查看登陆状态是否为真。

这样我们就区分出了登录用户和未登录用户。

如何在服务器端找到当前用户对应的Session?

我们之前提到,在服务器端储存Session的每一个小格子,都有一个独一无二的session_id作为唯一标识,所以我们可以用这个session_id去找到当前用户对应的Session储存。但是这就衍生出了一个问题: 既然HTTP协议是无状态的,那我怎么知道当前Post请求就是之前那个用户发出的呢?就算我知道了当前用户就是之前登陆的用户,我又如何获取用户对应的session_id呢?

我们可以用Cookies解决这个问题:

解决思路与之前相似,既然HTTP协议是无状态的,我们把状态存储下来就好。既然不知道如何获取用户对应的session_id,那么在用户登陆后,将用户对应的session_id存储到浏览器本地,然后每次发送请求时,前端都把这个session_id携带上去,然后后端不就知道当前的请求是哪个用户发出的了吗。

后端通过前端携带的session_id,找到了服务器上存储的与用户相关的数据后,不久找到了之前用户的状态了吗?妙啊妙啊

相关推荐
JarvanMo1 分钟前
如何在Dart 3.8中配置更新后的代码格式化工具
前端
yinshimoshen2 分钟前
根据S-T教学分析法绘制图形-前端实现
前端·canvas
龚思凯4 分钟前
Node.js 模块导入语法变革全解析
后端·node.js
五点六六六4 分钟前
一些关于TreeShaking的AST的理解
前端·javascript·前端工程化
清粥油条可乐炸鸡5 分钟前
tree 树组件大数据卡顿问题处理
前端
天行健的回响6 分钟前
枚举在实际开发中的使用小Tips
后端
wuhunyu12 分钟前
基于 langchain4j 的简易 RAG
后端
techzhi12 分钟前
SeaweedFS S3 Spring Boot Starter
java·spring boot·后端
zhangxingchao27 分钟前
Android开发者如何快速上手Flutter开发
前端
空&白42 分钟前
css元素的after制作斜向的删除线
前端·css