8.HTTP的三种状态管理:session-based、cookie-based、token-based

http是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的。当然它知道是哪个客户端ip地址发过来的,但是对于我们的应用来说,我们是靠用户来管理的,而不是靠客户端ip地址来管理的。所以对于我们的应用而言,它是需要有状态管理的,以便服务器能够准确的知道http请求是哪个用户发起的,从而判断他是否有权限继续这个请求。

1. 基于服务器的session-based状态管理

.HTTP的三种状态管理:session-based、cookie-based、token-based"/
session-based

1)客户端把用户名和密码等登录信息放入报文的实体部分,通常是以 POST 方法把请求发送给服务器。而这时,会使用 HTTPS通信来进行 HTML 表单画面的显示和用户输入数据的发送。

<form action="https://foo.com/login.php" method="post">
  <div>
    <label for="username">Username:</label>
    <input type="text" name="username" id="username">
  </div>
  <div>
    <label for="password">Password:</label>
    <input type="password" id="password">
  </div>
  <div>
    <button type="submit">登陆</button>
  </div>
</form>
POST /login.php HTTP/2.0
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 33

username=zhangsan&password=secret

2)启动一个会话,首先验证用户名和密码的格式长短等是否有效,如果无效,闪现会话抛出异常信息,如果有效,连接数据库进行身份认证,首先查找用户名是否存在,如果不存在,闪现会话抛出异常信息,如果用户名存在,则把密码和存储在数据库的“盐”再加计算量,哈希出最终密码摘要,与数据库的密码摘要进行比对,如果不匹配,闪现会话抛出异常信息。

//以PHP代码为例
//启动一个会话
session_start();

//获取用户名和密码
$userid = $_POST['userid'];
$password = $_POST['password'];

如果用户名存在且密码摘要匹配,就注册用户成功认证的会话变量$_SESSION(其中包括用以识别用户的 Session ID),向客户端返回响应时,会在响应报头中 Set-Cookie 内写入 SessionID(如 sessionid=38afes7a8)。

//注册会话变量
$_SESSION['valid_user'] = $userid;
$_SESSION['sessionid'] = 38afes7a8;
//响应报头
Set-Cookie: sessionId=38afes7a8

3)客户端接收到从服务器发来的 Session ID 后,会将其作为Cookie 保存在本地。当用户点击该网站的其他页面时,就再次向服务器发送请求,浏览器会自动发送Cookie,所以 Session ID 也随之发送到服务器。服务器端可通过会话变量$_SESSION验证接收到的 Session ID与服务器保存的 Session ID 来识别用户和其认证状态,如果匹配,就使用其他会话变量。

//使用会话变量
if(isset($_SESSION['valid_user']))
{
}

//销毁已注册变量
unset($_SESSION['myvar']);

//销毁会话
session_destroy();

缺点:

1)这种方式将会话信息存储在web服务器里面,所以当用户同时在线量比较大的时候,这些会话信息会占据比较大的内存;

2)当应用采用集群部署的时候,会遇到多台web服务器之间如何做session共享的问题。

3)多个应用要共享session时,如何做session共享的问题。

因为使用的是cookie客户端存储,自然cookie的缺点就是这种方式的缺点:

  • cookie是与特定域绑定的,设置cookie后,它会与请求一起发送到创建它的域,这个限制能保证cookie中存储的信息只对被认可的接收者开放,不被其他域访问从而引发有跨域需求的网站。
  • 每个域可以保存的cookie个数因浏览器不同而有所不同,IE和旧版Edge:50个(如果超过,会按照最近最少使用原则删除之前的cookie),Firefox:150个(好像随机删除),Safari和Chrome:没有硬性限制。
  • 每个cookie不超过4KB大小限制,因此每个域不超过80KB大小限制。

2. 基于客户端的cookie-based状态管理

与session-based的区别是:session-based状态存储在服务器,仅返回一个sessionid到客户端,而cookie-based恰恰相反,状态管理存储在客户端,保存的cookie越大,请求完成的时间越长,而且浏览器对cookie大小有限制,所以还是尽可能只通过cookie保存必要的信息,以免影响性能问题。

//服务器
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

//客户端
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

因为无论是session-based还是cookie-based都会用到cookie,所以cookie的缺点就是他们的相同点。

3.基于客户端的token-based状态管理

Web Storage 规范主要有两个目标:

  • 提供在cookie之外的存储会话数据的机制
  • 提供跨会话持久化存储大量数据的机制。

Web Storage 定义了两个对象:localStoragesessionStorage

localStorage是永久存储机制,sessionStorage是跨会话的存储机制。

token可以存储在客户端的localStorage或者sessionStorage里面。

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/basic/http/3693.html

发表评论

登录后才能评论