Cookie、Session和Token

一、COOKIE:

在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。

Cookie的弊端:

  • cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。
  • cookie 中的所有数据在客户端就可以被修改,数据非常容易被伪造
服务器端代码: 
if (req.cookies.jack) {
console.log(req.cookies.jack);
res.send("welcome");
} else {
res.cookie('jack', 'content', {maxAge: 60 * 1000});
res.send("no cookie");
}

Cookie的参数:

  • path:表示 cookie 影响到的路径,匹配该路径才发送这个 cookie。
  • expires 和 maxAge:告诉浏览器这个 cookie 什么时候过期,expires 是 UTC 格式时间,maxAge 是 cookie 多久后过期的相对时间。当不设置这两个选项时,会产生 session cookie,session cookie 是 transient 的,当用户关闭浏览器时,就被清除。一般用来保存 session 的 session_id。
  • secure:当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才有效。
  • httpOnly:浏览器不允许脚本操作 document.cookie 去更改 cookie。一般情况下都应该设置这个为 true,这样可以避免被 xss 攻击拿到 cookie。

二、SESSION:

为了解决cookie安全性问题,session应运而生。sessioncookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加的安全,不容易被窃取。session 的运作通过一个session_id来进行。当你浏览一个网页时,服务端随机产生一个 1024 比特长的字符串,然后存在你 (客户端)cookie 中的connect.sid字段中,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做server side session。

但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。

 服务器端代码:
app.use(session({
    secret:'jack2016',
// 建议使用 128 个字符的随机字符串,这里不写secret的话cookie存储的是不加密的sessionid
    name:'jacks',    //cookie名字,这里cookie存的内容是用secret加密的sessionid,
    cookie: {maxAge:60*2000},
}));

session的可选参数:

  • name: 设置 cookie 中,保存 session 的字段名称,默认为connect.sid。
  • store: session 的存储方式,默认存放在内存中,也可以使用 redis,mongodb 等。express 生态中都有相应模块的支持。
  • secret: 通过设置的 secret 字符串,来计算 hash 值并放在 cookie 中,使产生的 signedCookie 防篡改。
  • cookie: 设置存放 session id 的 cookie 的相关选项,默认为(default: { path: '/', httpOnly: true, secure: false, maxAge: null })
  • genid: 产生一个新的 session_id 时,所使用的函数, 默认使用uid2这个 npm 包。
  • rolling: 每个请求都重新设置一个 cookie,默认为 false。
  • resave: 即使 session 没有被修改,也保存 session 值,默认为 true。

三、加密的COOKIE

session数据加密,然后存储在cookie中。这种专业术语叫做client side session

比如,cookie 本应是{dotcom_user: 'alsotang'},如果我们签个名,比如把dotcom_user的值跟我的 secret_string 做个 sha1,cookie变成了

{
    dotcom_user: 'alsotang',
    'dotcom_user.sig': '4850a42e3bc0d39c978770392cbd8dc2923e3d1d',
}

这样一来,用户就没法伪造信息了。一旦它更改了 cookie 中的信息,则服务器会发现 hash 校验的不一致。毕竟他不懂我们的 secret_string 是什么,而暴力破解哈希值的成本太高。

 

四、Token认证

通过sesson_id解决http无链接的问题,但web server不能设计为必须接受cookie 因为不能保证访问都是浏览器发起的。

解决办法:JWT(Json Web Token)。在HTTP header中包含token信息进行验证。

JWT的第一部分是一个js对象,表面JWT的加密方法。

{
    "typ":"JWT",
    "alg":"HS256"
}

JWT的第二部分是token的核心,包含了一些信息。

{
  "business_id": [
    "1"
  ],
  "store_id": [
    "2",
    "4",
    "7",
    "996",
    "1021"
  ],
}

第三个是JWT根据第一部分和第二部分的签名(Signature)

 

 

posted on 2019-07-16 18:01  joannae  阅读(287)  评论(0编辑  收藏  举报

导航