目录

---------

问题的由来

HTTP 协议是无状态的,这意味着如果客户端每次要与服务端通信,都必须重新与服务端连接,客户端请求一次,服务端才会响应一次,每一次请求都与之前的请求无关。

这样会产生的问题:

为了解决这些问题,便诞生了 cookietokensession,他们可以“知道”发起请求的客户端是谁,进而解决客户端标识问题(权限问题)。

cookietokensession 相当于赋予客户端身份证,我们可以通过“身份证”判断发起请求的是谁

Cookie

cookie 是保存在客户端(浏览器)中的一小块数据,大小限制在 4KB 左右。目前 cookie 存储数据的方式逐渐被取代,原因如下:

受害者 ↓

<div align=center> <iframe class="aspect-ratio" src="https://player.bilibili.com/player.html?bvid=BV1VY4y1Q7LC&&page=1&as_wide=1&high_quality=1&danmaku=0" scrolling="no" border="0" frameborder="no" framespacing="0" high_quality=1 danmaku=1 allowfullscreen="true"> </iframe> </div>
属性名含义
namecookie 的名称
valuecookie 的值
commentcookie 的描述信息
domain可以访问该 cookie 的域名
expirescookie 的过期时间,具体某一时间
maxAgecookie 的过期时间,比如多少秒后 cookie 过期。
pathcookie 的使用路径,
securecookie 是否使用安全协议传输,比如 SSL 等
versioncookie 使用的版本号
isHttpOnly指定该 Cookie 无法通过 JavaScript 脚本拿到,比如 Document.cookie 属性、XMLHttpRequest 对象和 Request API 都拿不到该属性。这样就防止了该 Cookie 被脚本读到,只有浏览器发出 HTTP 请求时,才会带上该 Cookie。

cookie 的操作流程很简单,大致分为以下几步:

  1. 客户端向服务端发起请求

  2. 服务端接收到请求,之后生成一个 session 会话

  3. 服务端响应客户端,并在想用投中设置 Set-Cookie,里面包含了 sessionId,格式为:

    PlainText
    Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
    

    其中,sessionId 用来标识客户端

  4. 客户端收到服务端的请求,如果服务器给了 Set-Cookie,name浏览器在下一次请求中就会在请求头上自动携带 cookie

  5. 客户端再次发起请求,并自动携带了 cookie,cookie 也携带了用户信息

  6. 服务端收到请求,验证 cookie 信息,比如通过 sessionId 来判断会话是否存在,存在继续响应,否则不响应

图解(来自图解 HTTP):

在浏览器操作 cookie 的操作使用较少,了解即可(别像老莱一样就可以了):

  1. 禁用所有 cookie
  2. 删除 cookie
  3. 查看 cookie

浏览器进入设置,搜索cookie,就可以进行上述操作了

如果要查看某个网页的 cookie 数据,可以点击地址栏左边的小锁,如图:

Session

session:会话,主要由服务端创建,主要作用就是保存 sessionId,用户与服务端之间的权限确认主要是通过这个 sessionId。

Session 的描述:

session 由服务端创建,当一个请求发送到服务端时,服务器会检索该请求里面有没有包含 sessionId 标识,如果包含了 sessionId,则代表服务端已经和客户端创建过 session,然后就通过这个 sessionId 去查找真正的 session,如果没找到,则为客户端创建一个新的 session,并生成一个新的 sessionId 与 session 对应,然后在响应的时候将 sessionId 给客户端,通常是存储在 cookie 中。如果在请求中找到了真正的 session,验证通过,正常处理该请求

客户端与服务端连接,服务端都会为该客户端创建一个 session,并肩 session 中的 sessionId 作为唯一标识,通过设置 Set-Cookie 头的方式响应给客户端,客户端将 sessionId 存到 cookie 中。

通常情况下,cookie 和 session 结合使用

首先 Cookie 和 Session 都是基于 sessionId 实现的。而 session 是基于 cookie 实现的,主要有以下特点:

如果想要实现鉴权,cookie 和 session 都可以单独使用,但是建议两者结合使用

Session 的缺点

  1. session 的创建有很大的随意性,代码可读性和维护性降低
  2. 客户端连接,服务器每次都要重新生成 session,占用服务器资源,性能差
  3. 容易遭受 CSRF 攻击(跨站请求伪造)

Token

服务端可以通过 token(令牌)来确认身份,可以解决 session 和 cookie 的缺点

token 的组成

token 其实就是一串字符串而已,只不过它是被加密后的字符串,它通常使用 uid(用户唯一标识)、时间戳、签名以及一些其它参数加密而成。我们将 token 进行解密就可以拿到诸如 uid 这类的信息,然后通过 uid 来进行接下来的鉴权操作。

token 的生成

前面我们说 cookie 是服务端设置了 set-cookie 响应头之后,浏览器会自动保存 cookie,然后下一次发送请求的时候会自动把 cookie 携带上。但是我们说 cookie 算是一种民间的实现方式,所以说浏览器自然不会对它进行成么处理。token 主要是由服务器生成,然后返回给客户端,客户端手动把 token 存下来,比如利用 localstorage 或者直接存到 cookie 当中也行。

token 认证流程

  1. 客户端发起登录请求,比如用户输入用户名和密码后登录。
  2. 服务端校验用户名和密码后,将用户 id 和一些其它信息进行加密,生成 token。
  3. 服务端将 token 响应给客户端。
  4. 客户端收到响应后将 token 存储下来。
  5. 下一次发送请求后需要将 token 携带上,比如放在请求头中或者其它地方。
  6. 服务端 token 后校验,校验通过则正常返回数据。

Session 和 Token 如何选择

对于服务端渲染前后端分离这两种开发模式来说,分别有着不同的身份认证方案:

  1. 服务端渲染推荐使用 Session 认证机制
  2. 前后端分离推荐使用 JWT 认证机制(Token)

Nodejs 实战

转至:前后端授权的代码实现(cookie、session、token) | Plumbiuの小屋