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

express中cookie的使用和cookie-parser的解读的更多相关文章

  1. express中 使用session与cookie

    1.express如何使用session与cookie : https://www.jianshu.com/p/1839e482274e  或  https://www.cnblogs.com/chy ...

  2. express中cookie的使用

    一.Cookie 简介● cookie 是存储于访问者的计算机中的变量.可以让我们用同一个浏览器访问同一个域名的时候共享数据.● HTTP 是无状态协议.简单地说,当你浏览了一个页面,然后转到同一个网 ...

  3. 【jQuery基础学习】04 jQuery中的表格操作及cookie插件的使用

    这章本来准备写成jQuery的表单操作和表格操作的. 然而昨天吧jQuery的表单操作看完,发现全部在炒之前章节的剩饭,所以就没写出来. 那么今天就来看看表格吧. 因为平常做的都是公司的内部管理系统, ...

  4. 从WebBrowser中取得Cookie 和 WebClient设置cookie!

    原文:从WebBrowser中取得Cookie 和 WebClient设置cookie! 从WebBrowser中取得Cookie 的代码 CookieContainer myCookieContai ...

  5. tp框架中的一些疑点知识--cookie和session的配置

    不同的浏览器采用不同的方式保存Cookie. IE浏览器会在"C:\Documents and Settings\你的用户名\Cookies"文件夹下以文本文件形式保存,一个文本文 ...

  6. 【转】分享前端开发中通过js设置/获取cookie的一组方法

    在前端开发中,通常都需要获取并记录用户的某些操作设置,这样可以使用户下一次访问网站时不用进行重复的调整设置同一个功能. js方法的完整代码如下: var cookie = { set:function ...

  7. [zz]【整理】Python中Cookie的处理:自动处理Cookie,保存为Cookie文件,从文件载入Cookie

    http://www.crifan.com/python_auto_handle_cookie_and_save_to_from_cookie_file/ #!/usr/bin/python # -* ...

  8. 使用JQGrid中可见列并存入Cookie

    引入js与css <link href="~/Content/js/jquery-ui/jquery-ui.min.css" rel="stylesheet&quo ...

  9. nodejs+express中设置登录拦截器

    在nodejs+express中,采用nodejs后端路由控制用户登录后,为了加强前端的安全性控制,阻止用户通过在浏览器地址栏中输入地址访问后台接口,在app.js中需要加入拦截器进行拦截: /*** ...

随机推荐

  1. hdu4115:Eliminate the Conflict

    n<=10000局剪刀石头布,对面第i局出Ai,m<=10000种对你出什么提出的要求:Xi Yi Wi 表示第Xi局和第Yi局,Wi=1:必须不同:Wi=0:必须相同,问是否存在你一局都 ...

  2. CERC 2014 (动态树+主席树)

    CERC 2014 Pork barrel Problem : n个点m条边有边权的无向图,有q个询问,每次询问权值在[L,R]内的边组成的最小生成树的权值和,强制在线. n <= 1000, ...

  3. hdu 2736 Average distance

    传送门 Average distance Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  4. 进程&进程池

    进程 服务器中, s.listen(n) n不能无限大,以为内存不可能无限大,n表示内存同一时间接纳的等待连接数,可以看成一个(队列),取出一个拿去建立连接,然后再放进一个,队列中一直保持n个连接 请 ...

  5. linux修改PS1,自定义命令提示符样式

    目录 参数说明 修改颜色 linux默认的命令提示符是这样的: 白色的,如果当前执行的命令很多的话,一整块屏幕上全是一堆输出信息,上一条命令在哪?我刚输入的命令在哪?找的头晕.有没有办法可以修改命令提 ...

  6. 【面试被虐】如何只用2GB内存从20亿,40亿,80亿个整数中找到出现次数最多的数?

    这几天小秋去面试了,不过最近小秋学习了不少和位算法相关文章,例如 [面试现场]如何判断一个数是否在40亿个整数中? [算法技巧]位运算装逼指南 对于算法题还是有点信心的,,,,于是,发现了如下对话. ...

  7. Meteor会话

    会话用于当用户在使用应用程序时保存数据.当用户离开应用这些数据将被删除. 在本教程中,我们将学习如何设置会话对象,存储一些数据并返回数据.我们将使用基本的HTML设置. meteorApp/impor ...

  8. awk基本使用方法简单介绍

    之前说过sed, 今天来说awk, 它也是一个文本处理器. 是linux下的一个命令, 比sed更强大. 搞linux开发, 尤其是后台开发, 这个命令差点儿必需要用到. awk这三个字母分别代表其三 ...

  9. 基于编程人员Python学习第一章节

    基于廖雪峰的python零基础学习后,自我总结.适用于有一定基础的编程人员,对我而言,则是基于.net已有方面,通过学习,记录自我觉得有用的地方,便于后续回顾. 主要以快速定位内容,通过直观代码输入输 ...

  10. C语言细节笔记1

    /******************************************************************************* ——笔记 1. 函数申明的书写. 可以 ...