express中cookie的运用和cookie-parser的解读

最近在研讨express,学着运用cookie,最先不会用,就百度了一下,没有百度到迥殊完全的解答。查阅了express的API,综合了网友的博客,解读了cookie-parser的源码,以及运用WebStorm和Chrome考证,终究邃晓了express中cookie的运用。顾此篇文章等于分享也是总结。

1. cookie的建立

express直接供应了api,只须要在须要运用的处所挪用以下api即可


    function(req, res, next){
        ...
        res.cookie(name, value [, options]);
        ...
    }

express就会将其填入Response Header中的Set-Cookie,到达在浏览器中设置cookie的作用。

  • name: 范例为String

  • value: 范例为String和Object,假如是Object会在cookie.serialize()之前自动挪用JSON.stringify对其举行处置惩罚

  • Option: 范例为对象,可运用的属性以下

       domain:cookie在什么域名下有用,范例为String,。默以为网站域名
       expires: cookie逾期时候,范例为Date。假如没有设置或许设置为0,那末该cookie只在这个这个session有用,即封闭浏览器后,这个cookie会被浏览器删除。
       httpOnly: 只能被web server接见,范例Boolean。
       maxAge: 完成expires的功用,设置cookie逾期的时候,范例为String,指明从现在最先,若干毫秒今后,cookie到期。
       path: cookie在什么途径下有用,默以为'/',范例为String
       secure:只能被HTTPS运用,范例Boolean,默以为false
       signed:运用署名,范例Boolean,默以为false。`express会运用req.secret来完成署名,须要cookie-parser合营运用`
       

    上面是我连系试验和本身的明白,对官网api的翻译。原英文以下:

《express中cookie的运用和cookie-parser的解读》

用例以下

res.cookie('name', 'koby', { domain: '.example.com', path: '/admin', secure: true });
//cookie的有用期为900000ms
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
//cookie的有用期为900000ms
res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true });

//cookie的value为对象
res.cookie('cart', { items: [1,2,3] });
res.cookie('cart', { items: [1,2,3] }, { maxAge: 900000 });

res.cookie('name', 'tobi', { signed: true });

2.cookie的删除
express直接供应了api删除浏览器中的cookie,只须要在须要运用的处所挪用以下api即可


    function(req, res, next){
        ...
        res.clearCookie(name [, options]);
        ...
    }

3.应用cookie-parser读取cookie
cookie-parser是一个异常好用轻易的插件,能够直接用在express和connect中,官文地点为https://www.npmjs.com/package/cookie-parser。npm装置敕令

$npm install cookie-parser --save

运用体式格局

var express = require('express');
var cookieParser = require('cookie-parser');

var app = express();
//不运用署名
app.use(cookiePareser());

//若须要运用署名,须要指定一个secret,字符串,否者会报错
app.use(cookiePareser('Simon'));
  • 假如没有为signed功用,cookie-parser经由过程以下代码剖析req.headers.cookie

        //index.js
        var cookie = require('cookie');
        var parse = require('./lib/parse');
        
        if (req.cookies) return next();    //假如存在req.cookies跳过这个middleware
        var cookies = req.headers.cookie;    //保留对象地点,进步运转效力
        req.cookies = Object.create(null);    //建立一个对象,剖析后的且未运用署名的cookie保留在req.cookies中
        req.cookies = cookie.parse(cookies);    //与express中挪用cookie.serialize()对应,剖析cookie
        req.cookies = JSONCookies(req.cookies);    // JSON字符序列转化为JSON对象
        //./lib/parse.js
        
        //继续cookie中的JSON字符序列
        exports.JSONCookies = function(obj){
          var cookies = Object.keys(obj);    //猎取obj对象的property
          var key;
          var val;
        
           //轮回推断并剖析
          for (var i = 0; i < cookies.length; i++) {
            key = cookies[i];
            val = exports.JSONCookie(obj[key]);
        
            //假如是JSON字符序列则保留
            if (val) {
              obj[key] = val;
            }
          }
        
          return obj;
        };
        
       //剖析JSON字符序列
        exports.JSONCookie = function(str) {
          if (!str || str.substr(0, 2) !== 'j:') return; //推断是不是为JSON字符序列,假如不是返回undefined
        
          try {
            return JSON.parse(str.slice(2));    //剖析JSON字符序列
          } catch (err) {
            // no op
          }
        };
  • 假如运用了signed功用,cookie-parser经由过程以下代码剖析req.headers.cookie

        //index.js
        var cookie = require('cookie');
        var parse = require('./lib/parse');
        
        if (req.cookies) return next(); //假如存在req.cookies跳过这个middleware
        
        //挪用res.cookie(name, value , {singed: true}),express会运用req.secret。故运用了署名功用,需给cookie-parser通报secret,且res.cookie(name, value , {singed: true})需在cookie-parser插        
        //入express后再运用
        req.secret = secret;     
        req.cookies = Object.create(null);
        req.signedCookies = Object.create(null); //建立req.singedCookies,一切剖析后的signed cookie都保留在这个对象中,req.cookies中没有任何signed cookie
    
        // 假如要求中没有cookies
        if (!cookies) {
          return next();
        }
    
        req.cookies = cookie.parse(cookies, options); //与express中挪用cookie.serialize()对应,剖析cookie
    
        // parse signed cookies
        if (secret) {
          //推断是不是为singed cookie。假如是,则去掉署名,同时删除req.cookies中对应的property,将这些去掉署名的cookie构成一个对象,保留在req.signedCookies中
          req.signedCookies = parse.signedCookies(req.cookies, secret); 
          // JSON字符序列转化为JSON对象
          req.signedCookies = parse.JSONCookies(req.signedCookies);    
        }
    //./lib/parse.js
    var signature = require('cookie-signature');

    exports.signedCookies = function(obj, secret){
      var cookies = Object.keys(obj);    //猎取obj对象的property
      var dec;
      var key;
      var ret = Object.create(null);  //建立返回对象
      var val;
    
      for (var i = 0; i < cookies.length; i++) {
        key = cookies[i];
        val = obj[key];
        dec = exports.signedCookie(val, secret);
    
        //推断是不是是去掉署名后的value,假如是保留该值到ret中同时删除obj中的响应property
        if (val !== dec) {
          ret[key] = dec;
          delete obj[key];
        }
      }
    
      return ret;
    };

    exports.signedCookie = function(str, secret){
        //推断是不是添加了署名,假如添加了署名则去掉署名,不然返回原字符串
      return str.substr(0, 2) === 's:' 
        ? signature.unsign(str.slice(2), secret)
        : str;
    };

综上所诉,剖析后的unsigned cookie保留在req.cookies中,而剖析后的signed cookie只保留在req.signedCookies中。运用cookie-parser插件,后续代码直接运用req.cookies或许req.signedCookies即可

    原文作者:xiemengguilin
    原文地址: https://segmentfault.com/a/1190000004139342
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞