express中cookie的使用和cookie-parser的解讀


https://segmentfault.com/a/1190000004139342?_ea=504710

 

 

最近在研究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的翻譯。原英文如下:

用例如下

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即可


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM