nodejs之cookie和session

因为最近工做须要又将node捡了起来。翻了下以前的笔记,想着把几篇比较详细的整理下分享出来。第一篇就来讲说常常会用到的cookie&session。node

由来

众所周知http是一个无状态的协议,服务端没法跟踪客户端的状态。那么就会致使一个问题,如咱们以管理员身份登陆一个后台管理系统,登陆成功后跳转到管理页面,那在咱们进行操做时,服务器怎么知道咱们是否已经登陆过了呢?mysql

cookie

为了解决上面的问题,cookie诞生了。redis

cookie是http协议中的一部分,浏览器向服务器发请求,成功后服务器向浏览器返回一个cookie,那么之后浏览器向服务器发送的全部请求都会携带这个cookie。sql

首先安装express框架,固然你也可使用koa。这里演示代码都是express。
在express中cookie不是自带的,因此须要安装对应的中间件进行操做,koa中的cookie就是框架自带的就不须要另外安装。数据库

安装cookie-parser中间件express

npm i cookie-parser -Dnpm

写cookie跨域

安装成功后,先引入cookie-parser。而后在任意路由中去尝试写一个cookie浏览器

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

let server = express();
server.listen(8080);

// 使用中间件
server.use(cookieParser());

server.get('/index',(req, res) => {
    // 使用了中间件后就能够访问req和res上的cookies对象
    console.log(req.cookies);
    // 写cookie
    res.cookie('num', 10, {
        // domain: 'xxx.com',
        // path: '/',
        maxAge: 24 * 3600 * 1000
    })
    res.send('ok');
})

cookie的读取和设置都很简单,设置的时候有一些可选参数,安全

  • domain:存储的域名,cookie是不跨域的,而且存储在主域名中子域名是能够访问到的,可是若是存在子域名中那么主域名是没法访问的。因此这里通常是存在主域名,避免子域名访问不到cookie。
  • path:存储路径,与domain相似,因此通常也是指定根路径。
  • maxAge:有效期(毫秒)

运行下代码,而后到浏览器中查看刚刚写入的cookie
在这里插入图片描述
打开浏览器F12,到Application中找到Cookies,就能够看到刚刚写入的cookie,名字和值以及有效期都是咱们设置的。再次刷新后咱们也能够在命令行中看到服务器打印的cookie。
在这里插入图片描述
简单的cookie读写就完成了。

安全隐患

这里咱们能够知道cookie是存在浏览器中的,而且请求服务器的时候会一并带过去。这样就必定会有安全隐患,咱们先把服务器写cookie的逻辑注释掉,从新运行服务器,而后尝试在浏览器中手动修改cookie。
在这里插入图片描述
这里咱们将值修改成10000。刷新页面后在命令行中能够看到服务器获取的值就是10000。
在这里插入图片描述
cookie就这样很容易的在浏览器中被咱们修改了。若是cookie存了一些比较重要的数据,后果会很是严重。

cookie签名
怎么样才能作到让服务器验证cookie准确性,让服务器发现cookie是否被人为修改。
就要用到cookie签名。修改下服务器代码。

// 密钥
server.use(cookieParser(
  'dasdasdasdasfewg315nkl23k1ml41m24kl1nm5kol312n5kl32n5oj3n4oi1jm4o1k2m4'
));

在使用cookieParser中间件的时候加入一个签名密钥,通常是随机生成的一个字符串
而后在设置cookie的时候加入几个参数。

server.get('/index',(req, res) => {
    // 签名后的cookie须要经过signedCookies访问
    console.log(req.signedCookies);
    res.cookie('num', 10, {
        // httpOnly: true,
        // secure: true,
        signed: ture
        maxAge: 24 * 3600 * 1000
    })
    res.send('ok');
})
  • httpOnly:设置cookie只能由服务器操做,前台看不到
  • secure:只有在https的状况下才能使用cookie
  • singed:设置cookie是否签名

这里我先现开启签名。而后运行代码
在这里插入图片描述
能够看到这回的cookie是一串乱码。将乱码复制出来是这样的。
s%3A10.y4%2BaUbiQxjUS%2FvaGtU%2BaZnAZ9WxVHXy3O0zr%2BgoCdGk
%3A表明":",转换下获得以下:
s:10.y4%2BaUbiQxjUS%2FvaGtU%2BaZnAZ9WxVHXy3O0zr%2BgoCdGk
经过以上得出签名后的cookie格式为:
s:值.签名
这样若是咱们尝试修改其中的值,还会不会生效了呢?
将服务器设置cookie的代码注释掉,只打印cookie,而后在浏览器中修改cookie。
在这里插入图片描述在这里插入图片描述
修改后的cookie由于没法经过服务器的签名验证,因此是没法获取的。这样就确保了cookie的安全性,虽然签名能够增长cookie的安全性,可是增大致积,因为cookie只有4k的存储空间,因此咱们只签名重要的信息。

session

cookie 虽然很方便,可是使用 cookie 有一个很大的弊端,就是存储在浏览器,虽然说能够对cookie进行签名,可是也不能保证cookie的绝对安全,而且将重要的信息存在客户端自己就是不安全的事情。同时cookie也受限于大小。为了解决这些问题session也诞生了。

session 中的数据是保留在服务器端的。session不会单独存储,会有标识,这个标识叫作session_id 或者 token。而且session是强制加密的。

一样咱们须要另外一个中间件操做session,cookie-session
npm i cookie-session -D
使用方式与cookie-parser相似,先引入cookie-session

const cookieSession = require('cookie-session');

而后进行循环密钥签名,密钥通常是经过程序生成的,可能几千几万条,这里方便演示,只写几条。

server.use(cookieSession({
  keys: ['dasdas21fsdffedsfds4das21321', 'safdas454325235325trgtrthdfthd', '21ed2rf3245r23r2354r235235'],
  maxAge: 20 * 60 * 1000      // 有效期20分钟
}));

而后在接口中设置和获取session

server.get('index', (req, res) => {
    console.log(req.session);
    res.session['num'] = 10;
    res.send('ok');
});

运行代码,打开浏览器调试工具找到cookies,
在这里插入图片描述
cookie中有两个值,一个是session,一个是session.sig
将服务器中设置session的代码注释掉,再刷新页面,能够看到命令行中就打印了咱们设置的session值。
在这里插入图片描述
就算其余用户经过session劫持拿到了咱们的session值,可是每一个用户的session.sig签名是经过循环密钥生成的,数量庞大的循环密钥相同的概率很小。而且在浏览器手动修改session后,服务器也会感知到这个session和session.sig不是对应的。确保数据的安全性。同时也能够经过更换循环密钥和减小session有效期来提高安全性。

须要注意的是session是存在服务器的文件中。读写比较消耗性能。咱们能够将其保存在redis、内存、数据库中以优化性能。(如使用mysql-session)

相关文章
相关标签/搜索