Node的cookie和session

1,958 阅读1分钟

cookie

    // cookie 存储 4k (每次发请求的时候都会带上cookie) 鉴权  jwt模式
    // localStorage 5m (只存在浏览器上)
    
    // cookie (不安前 签名算法) session(基于cookie的,服务器的)   localStorage sessionStorage(浏览器关掉就没有了)
    
    // 设置cookie 有个方案 浏览器设置  服务端设置
    
    let http = require('http');
    let querystring = require('querystring');
    let crypto = require('crypto');
    // 1)默认cookie只对当前域名生效 (cookie不能给不同的域设置cookie)
    // 2)一级和二级域名可以共用cookie (配置)
    // 3) expires 绝对的时间 
    // 4) maxAge 过多长时间失效
    // 5) domain
    http.createServer(function (req, res) {
      // 设置cookie 和 读取cookie的方法
      let cookies = req.headers['cookie']
      req.cookies = querystring.parse(cookies,'; ','='); //name=123; age=9
      req.signedCookie = function (key) {
        // zfpx.asdasfghmfs
        let [k, sign] = (req.cookies[key]||'').split('.');
        // 当取值的时候 将内容在次签名比对 发现有篡改就把这个cookie抛弃掉
        let newSign = crypto.createHmac('sha256', 'zfpx').update(k).digest('base64').replace(/\+/g, '')
        console.log(newSign,sign)
        if (newSign == sign){
          return k;
        }else{
          return '';
        }
      }
      let arr = []
      res.setCookie = function (key, value, opts = {}) {
        if(opts.signed){ // 要把这个值进行签名
          value = value+'.'+crypto.createHmac('sha256', 'zfpx').update(value).digest('base64').replace(/\+/g,'');
        }
        let str = `${key}=${value}`;
        if (opts.maxAge){
          str+= `; max-age=${opts.maxAge}`
        }
        if (opts.httpOnly) {
          str += `; httpOnly`
        }
        arr.push(str);
        res.setHeader('Set-Cookie', arr)
      }
      if (req.url === '/read') { // 读取cookie
        res.end(req.signedCookie('name'));
      }
      if (req.url === '/write') { // 像浏览器写入cookie
        // 多个cookie设置 用数组的方式
        // res.setHeader('Set-Cookie', ['name=zfpx; max-age=10, 'age=9']);
        // res.setHeader('Set-Cookie',['name=zfpx; max-age=10; domain=.zf1.cn','age=9']);
        // res.setHeader('Set-Cookie', ['name=zfpx; path=/write', 'age=9']);
        // res.setHeader('Set-Cookie','name=zfpx; httpOnly=true'); // 前端不能获取服务端设置的cookie
        res.setCookie('name', 'zfpx', { httpOnly: true,signed:true });
        res.setCookie('age', '9', { httpOnly: true, maxAge: 3 });
        res.end('write Ok');
      }
    }).listen(3000);

session(存在于服务器端,相对安全)

    let http = require('http');
    let uuid = require('uuid');
    let querystring = require('querystring');
    let session = { // 内存 redis / mongo
    
    }
    // 给用户设置一个cookie
    let cardId = 'connect.sid'; // 名字 
    http.createServer(function (req,res) {
      // 拿到所有的cookie 看看用户是否有这张卡
      let cookies = querystring.parse(req.headers['cookie'],'; ');
      let cid = cookies[cardId];
      if(req.url === '/visit'){
        if (cid) { // 卡号
          if (session[cid]) { // 去session查找有没有卡
            session[cid].m = session[cid].m - 1000;
            res.end(`额度还有` + session[cid].m)
          } else {
            let id = uuid.v4(); // 卡号
            res.setHeader('Set-Cookie', `${cardId}=${id}`);
            session[id] = {
              m: 1000
            };
            res.setHeader('Content-Type', 'text/html;charset=utf-8');
            res.end(`卡中额度1000`);
          }
        } else {
          let id = uuid.v4(); // 卡号
          res.setHeader('Set-Cookie', `${cardId}=${id}`);
          session[id] = {
            m: 1000
          };
          res.setHeader('Content-Type', 'text/html;charset=utf-8');
          res.end(`卡中额度1000`);
        }
      }
    }).listen(3000);