Cookie和Session在Node.JS中的实践(三)

前面作者写的COOKIE篇SESSION篇,算是已经比较详细的说明了两者间的区别、机制、联系了。阅读时间可能稍长,因为作者本身作图也做了不短时间,都是为了能形象的把COOKIESESSION的运行原理描述出来,但花点时间去阅读理解他们是值得的。因为这个技术点虽然小,但涉及到前后端交互,无论是做前端还是后台,都需要懂。不然,只会遭同事鄙视……所以,为了不被鄙视,还是好好读多点书,充实自己。

如果还未搞懂COOKIE和SESSION的,建议去看看前面的两篇文章,再来看本篇,本篇主要重在实践,而不会再细讲原理性的东西。

设置COOKIE

使用原生NODE会让代码变得更复杂一些,为了方便演示代码这里使用到NODE.JS的框架Express,反正我们主要是讲COOKIE,框架无影响。

const express = require('express');

var server = express();

server.use('/cnblogs/wljqds', (req, res) => {
// 给客户端返回一个cookie
res.cookie('user', 'wljqds', {
path: '/cnblogs/wljqds',
maxAge: 20*60*1000
});
res.send('ok');
}); server.listen(8080);

运行结果:(在浏览器中输入localhost:8080/cnblogs/wljqds)

根据cookie篇中的说法,这个时候在响应首部(Response)应该会有Set-Cookie字段(在第一篇中有写到)

path对COOKIE访问的影响

domain和path字段结合起来就能限制浏览器对COOKIE的访问,在domain都是默认的情况下(一般而言都是根域名),只有path起作用,在COOKIE篇,用博客园为例说明了,在此我们可以用自己的代码说明,在上述代码中我们设置COOKIE的path值为path: '/cnblogs/wljqds',其实只要理解一点下级目录可以用上级目录的cookie,反之不可则容易了,为了说明这种情况,相对上述代码添加一个上级目录路由以及一个下级目录。

const express = require('express');

var server = express();

// 相对path: '/cnblogs/wljqds'来说,/是上级目录
server.use('/', (req, res) => {
res.send('ok');
});
// 相对path: '/cnblogs/wljqds'来说,/cnblogs/wljqds/article是下级目录
server.use('/cnblogs/wljqds/article', (req, res) => {
res.send('ok');
});
server.listen(8080);

在运行代码前,我有必要说明一点:前面我们已经保存了一个cookie了,这时候我们只是去查看cookie,验证path对cookie的限制。

首先,是根路径是否能访问cookie,访问根路径localhost:8080/

localhost:8080根路径下,没有任何的cookie,说明上级不能访问下级的cookie。

另外一个在此由于篇幅问题不在演示,读者们可以用代码自己尝试,记住一点:cookie对下级目录可以访问,但上级不可以。

设置COOKIE签名

其实在COOKIE篇中,有一个非常重要的概念没有谈及,那就是COOKIE签名,一些重要的信息保存在COOKIE,这时候是要COOKIE的。在这里补充知识,并且说明如何设置COOKIE签名。

首先COOKIE签名的作用是防止COOKIE被篡改!,通过在服务端验证签名从而能做到防止COOKIE篡改。

函数签名这个概念,需要从两个方面理解:

1.服务端把一个带签名COOKIE发送到客户端:服务端会生成一个秘钥,再使用加密算法比如HMAC-SHA256算法对COOKIE数据和秘钥一起加密得到一个签名,然后将这个签名加到COOKIE中,再发送给客户端。

2.服务端对客户端发送过来的COOKIE进行签名检验:当客户端再次发起请求的时候会将这个已经签名的COOKIE一起发送到服务器中,服务器中会把之前生成的秘钥跟COOKIE数据再次通过相同的算法进行加密,得到一个签名,再与发送过来的签名作对比,如果签名不相等,则证明COOKIE已经被篡改了!

通过上述的原理,代码实现COOKIE签名

const express = require('express');
const cookieParse = require('cookie-parser');
var server = express(); // 添加一个秘钥,通过秘钥生成签名与验证
server.use(cookieParse('qvqonvpasvoqsgf'));
server.use('/cnblogs/wljqds', (req, res) => {
// 给客户端返回一个cookie
res.cookie('user', 'wljqds', {
path: '/cnblogs/wljqds',
maxAge: 20*60*1000,
signed: true //设置签名为true
});
// 使用signedCookies,而不是cookies.因为是签名的COOKIE
console.log(req.cookies);
res.send('ok');
}); server.listen(8080);

控制台中输出: { user: 'wljqds' },浏览器中查看COOKIE,COOKIE值已经是加了一串签名。

读取COOKIE

读取cookie用到一个中间件cookie-parser,非常简单,需要注意一点就是。如果是签名的COOKIE,必须使用req.signedCookies

const express = require('express');
const cookieParse = require('cookie-parser');
var server = express(); server.use(cookieParse()); server.use('/cnblogs/wljqds', (req, res) => {
// 给客户端返回一个cookie
res.cookie('user', 'wljqds', {
path: '/cnblogs/wljqds',
maxAge: 20*60*1000
});
// 输出请求中的cookie
console.log(req.cookies);
// 删除一个COOKIE
res.clearCookies('user');
res.send('ok');
}); server.listen(8080);

运行结果在控制台中输出:{ user: 'wljqds' },简单暴力。

session

session的实践,记忆犹新,大一在学校上网站设计的课程,我们老师问网站用什么来维持登录状态……班上的人居然没人能回答,然后自己回宿舍去找相关资料,为的就是下次跟老师讨论……

session是依赖cookie的,所以它同样需要中间件cookie-parser,另外还需要cookie-session中间件。session配合项目使用就能明白他的强大。在此只做一个session的简单小例子:

使用session,简单的记录访问次数

const express = require('express');
const cookieParser = require('cookie-parser');
const cookieSession = require('cookie-session'); var server = express(); server.use(cookieParser('hnyetfsdnyth'));
// 设置session相关信息
server.use(cookieSession({
// keys是session的秘钥,越多越好,循环使用keys进行加密
keys: ['aaa', 'bbb', 'ccc'],
// session的名字
name: 'sessID',
// session的ID,不设置默认是关闭浏览器就过期
maxAge: 20*60*1000
})); server.get('/', (req, res) => {
//
if(req.session['count'] == null) {
// 设置COOKIE中一个count字段
req.session['count'] = 1;
} else {
req.session['count']++;
}
// 读取请求中的session
console.log(req.session['count']);
res.send('ok');
})
server.listen(8080);

每进行一次页面刷新,则相当于一次访问,输出台:

总结:

首先先说自己的写作感受,作者本人是第一次写文章,也不知道自己能表达清楚或者错误理解,后面会继续写自己所实践过的技术。

然后,COOKIE和SESSION的方方面面都已经写完了,不明白的可以讨论,作者花了挺多时间在作图上,不明白原理的话,图文结合多想几次,直到明白,这种技术点一定要半桶水,不然只会害了自己,坑了同事。

再说,这三篇文章其实涉及到的不止COOKIE和SESSION,前后端的交互作者都交待的挺清楚的,读者们能从我的文章中得到新的知识就OK,写文章的乐趣就在于分享

下次见。


如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!

Reference

1.https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie

2.https://www.cnblogs.com/moyand/p/9047978.html

3.https://nodejs.org/dist/latest-v8.x/docs/api/http.html#http_response_setheader_name_value

Cookie和Session在Node.JS中的实践(三)的更多相关文章

  1. Cookie和Session在Node.JS中的实践(二)

    Cookie和Session在Node.JS中的实践(二) cookie篇在作者的上一篇文章Cookie和Session在Node.JS中的实践(一)已经是写得算是比较详细了,有兴趣可以翻看,这篇是s ...

  2. Cookie和Session在Node.JS中的实践(一)

    Cookie和Session在Node.JS中的实践(一) Cookie和Session是一个非常有趣的概念,也是一个老生常谈的话题.然而,作者看了许多文章,也翻看了几本书籍,它们对Cookie和Se ...

  3. Node.js中的Session,不要觉得简单哦。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonnode/ .学习网站上有对应 ...

  4. 在node.js中使用COOKIE

    node.js中如何向客户端发送COOKIE呢?有如下两个方案: 一.使用response.writeHead,代码示例: //设置过期时间为一分钟 var today = new Date(); v ...

  5. Node.js中的不安全跳转如何防御详解

    Node.js中的不安全跳转如何防御详解 导语: 早年在浏览器大战期间,有远见的Chrome认为要运行现代Web应用,浏览器必须有一个性能非常强劲的Java引擎,于是Google自己开发了一个高性能的 ...

  6. 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

    Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...

  7. 如何在Node.js中合并两个复杂对象

    通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...

  8. Node.js 中MongoDB的基本接口操作

    Node.js 中MongoDB的基本接口操作 连接数据库 安装mongodb模块 导入mongodb模块 调用connect方法 文档的增删改查操作 插入文档 方法: db.collection(& ...

  9. 初步揭秘node.js中的事件

    当你学习node.js的时候,Events是一个非常重要的需要理解的事情.非常多的Node对象触发事件,你能在文档API中找到很多例子.但是关于如何写自己的事件和监听,你可能还不太清楚.如果你不了解, ...

随机推荐

  1. 用Chrome浏览器,学会这27个超好用功能

    一些非常有用的隐藏捷径 1. 想要在后台打开一个新的标签页而不离开现有的页面,这样就不会打断目前的工作了?按住 Ctrl 键或 Cmd 并点击它.如果你要在一个全新的窗口中打开一个链接,那就按 Shi ...

  2. Linux查看端口被占用情形

    查看某端口的占用情况: lsof -i:<端口号> 例如:lsof -i:8080 netstat -apn|grep <端口号> 例如: netstat -apn | gre ...

  3. 第二阶段团队冲刺-five

    昨天: 用servlet完成名单打印功能. 今天: 完成打印名单的功能. 遇到的问题: 在jsp中调用java方法与在main函数中的测试结果一致.

  4. HTML5初识Canvas

    HTML5初识Canvas <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  5. reinterpret_cast and const_cast

    reinterpret_cast reinterpret意为“重新解释” reinterpret_cast是C++中与C风格类型转换最接近的类型转换运算符.它让程序员能够将一种对象类型转换为另一种,不 ...

  6. Android M中 JNI的入门学习

    今年谷歌推出了Android 6.0,作为安卓开发人员,对其学习掌握肯定是必不可少的,今天小编和大家分享的就是Android 6.0中的 JNI相关知识,这是在一个安卓教程网上看到的内容,感觉很不错, ...

  7. Sth about 函数式编程(Functional Programming)

    今天开会提到了函数式编程,针对不同类型的百年城方式,查阅了一部分资料,展示如下: 编程语言一直到近代,从汇编到C到Java,都是站在计算机的角度,考虑CPU的运行模式和运行效率,以求通过设计一个高效的 ...

  8. axis2实践(一)JAX-WS入门示例

    1. 实例说明 现在大多数的网站都有通知功能(例如,放假通知,网站维护通知等),本实例就是针对于通知,发布两个WebService服务 1)根据供应商编号,状态,发布日期查询通知信息 2)根据编号查询 ...

  9. BZOJ3631 [JLOI2014]松鼠的新家 【树上差分】

    题目 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树"上.松鼠想 ...

  10. 身为多年的ubuntu用户。。。

    在这之前 说是多年也没有多年,事实上也就两年.. 不得不说一句,终于承受不住不稳定之重了... 个人觉得开始还是从centos开始比较好,比如说现在的我.. 之前看过的不知道在哪里的文章,谈论的是ub ...