express中的 Cookie和 Session

why Cookie and Session

我们为什么要引入Cookie和Session?因为HTTP是一个无状态的连接协议,为了支持客户端与服务器之间的交互,我们就需要通过不同的技术来交互存储状态,而这些不同的技术就是Cookie和Session.

通俗来说,客户端每次发出请求时,下一次请求无法得知上一次请求所包含的状态数据,把用户的状态数据关联起来就显得重要了。比如当我们在博客项目的某个页面进行了登录操作,那么当你跳转到 创建博客页面 浏览器是怎么判断你已经登录呢?这都需要用到Cookie和Session


express 中的Cookie###

req.cookies

因为 cookie 的格式为 name = value 格式,当cookie:name=yujuan ,req.cookies.name可以获取name对应的值,即

// cookie: name=yujuan
req.cookies.name
// => "yujuan"

res.cookie(name, value, [options])

设置cookie name值为value,[options]表示可选参数,其他可选的 cookie 参数会影响将 cookie 发送给服务器端的过程,主要有以下几种:

  • path:表示 cookie 影响到的路径,匹配该路径才发送这个 cookie。path 属性默认为 "/".
  • expires 和 maxAge:告诉浏览器这个 cookie 什么时候过期,expires 是 UTC 格式时间,maxAge (单位是毫秒)是 cookie 多久后过期的相对时间。当不设置这两个选项时,会产生 session cookie,意味着当用户关闭浏览器时,cookie就被清除。一般用来保存 session 的 session_id。
  • secure:当 secure 值为 true 时,前提是HTTPS 连接成功,这样浏览器和服务器就能加密传输数据——cookie 在 HTTPS 中有效,在 HTTP 中是无效。
  • httpOnly:浏览器不允许脚本操作 document.cookie 去更改 cookie。一般情况下都应该设置这个为 true,这样可以避免被 xss 攻击拿到 cookie。
    详细用法可看官网http://expressjs.jser.us/3x_zh-cn/api.html#res.cookie
看看在express中cookie的用法#####
// 首先引入 cookie-parser 这个模块
var cookieParser = require('cookie-parser');
// 使用 cookieParser 中间件,cookieParser(secret, options)
// options 传入上面介绍的 cookie 可选参数
app.use(cookieParser());

app.get('/', function (req, res) {
  // 如果请求中的 cookie 存在 isVisit, 则输出 cookie
  // 否则,设置 cookie 字段 isVisit, 并设置过期时间为1分钟
  if (req.cookies.isVisit) {
    console.log(req.cookies);
    res.send("再次欢迎访问");
  } else {
    res.cookie('isVisit', 1, {maxAge: 60 * 1000});
    res.send("欢迎第一次访问");
  }
});

express 中的Session###

cookie 虽然很方便,但是使用 cookie 有一个很大的弊端,cookie 中的所有数据在客户端就可以被修改,数据非常容易被伪造,那么一些重要的数据就不能存放在 cookie 中了,而且如果 cookie 中数据字段太多会影响传输效率。为了解决这些问题,就产生了 session,session 中的数据是保留在服务器端的

session 可以存放在 1)内存、2)cookie本身、3)redis 或 memcached 等缓存中 4)数据库中 . 放在数据库比前面三种查询速度慢,可是对什么时候会删除不太懂,是不是手动删除整张表呢——求解答哈哈

下面的实例代码session是存放在数据库的:

app.post('/check-login', (req, res, next)=> {
  User.findOne({username: req.body.username}, (err, doc)=> {
    if (err) {
      return (next(err));
    }
    if (!doc) {
      res.status(500).send({err: "该用户不存在"});
    }
    else {
      if (req.body.password === doc.password) {
        var randomId = uuid.v4();
        new Session({
          username: req.body.username,
          password: req.body.password,
          randomId: randomId
        }).save((err, doc)=> {

          res.cookie('user', randomId, {path: '/'});

          res.status(200).send({data: doc.username});
        })
      } else {
        res.status(500).send({err: "输入密码有误"});
      }
    }
  })
});

登录时发送用户名username和密码password的验证请求,验证通过则产生随机数randomId (一个 128比特的数字),将randomId,username,password数据保存到本地数据库的Session表中,并设置cookie user的值为randomId

接下来,说说express中Session的用处就是能根据自己设定的随机数randomId ,当请求到来时,服务端检查 cookie 中保存的 randomId 并通过这个 randomId 与本地数据库存储的Session表的数据关联起来,进行数据的获取,比如对用户名信息的获取,代码如下:

app.get('/verify-user-indentity',(req, res, next)=> {
  if (req.cookies.user) {
    Session.findOne({randomId: req.cookies.user}, (err, doc)=> {
      if (err) {
        return (next(err));
      }
      if (!doc) {
        res.status(500).send({err: "该用户不存在"});
      } else {
        res.status(200).send(doc.username);
      }
    })
  } else {
    res.status(403).send('');
  }
});

这样做的好处是,当我们下次访问时,因为设置过 cookie user的值为randomId. 所以cookie 会带有这个字符串,然后浏览器就知道你是上次访问过的某某某,然后从服务器的存储中取出上次记录在你身上的数据。由于字符串是随机产生的,而且位数足够多,所以也不担心有人能够伪造。

好了,就到这里。

每天都努力一点
谢谢你看完


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容