cookie

cookie用于判断用户是谁,一般都是使用签名算法进行加密。加上cookie本身大小有限制,总大小才32k,头信息也才32k,所有不能太大,而且不能太多,最多20条,容量这样一算的话,单条才4k。

koa创建cookie直接通过ctx对象:

ctx.cookies.set(key,value);

读取:

ctx.cookies.get(key);

签名

server.keys = ["aaaa", "bbbb", "cccc"];

router.get("/", async ctx => {
  ctx.cookies.set("name", "mulingyuer", { signed: true });
})

这样会在服务种一个key为name.sig,值已经被加密的cookie。

如果你要获取这个cookie,由于已经加密了,所有要这样写:

router.get("/", async ctx => {
  console.log(ctx.cookies.get("name", { signed: true }))
})

此时koa会将加密后的值获取并解析成原来的内容。

我们通过给server设置keys数组,里面存放一些密匙,然后再获取或者设置cookie是增加一个配置,就能做到签名,但是如何生成一堆随机的密匙呢?

生成密匙

生成密匙我们需要安装一个插件 uuid

npm i uuid

新版的uuid引入方法和旧版不同,官方示例:

const { v4: uuidv4 } = require('uuid');

uuidv4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'

也就是说通过解构的方式我们调用V4版本,uuid有好几个版本,v1,v2,v5,v4,我们使用v4就行了。

然后它本身就是一个函数,uuid会生成全局唯一id,理论上是不会出现重复的。

我们利用这个方法可以创建唯一的id,创建的话,也不用每次启动服务都创建,我们可以封装成一个文件,每次调用的时候生成一次文件并保存,下一次就直接使用文件。

const {
    v4: uuid
} = require("uuid");
const fs = require("fs");
const path = require("path");

let arr = [];
const n = 1024;
for (let i = 0; i < n; i++) {
    let str = "";
    for (let j = 0; j < 32; j++) {
        str += uuid().replace(/\-/g, "");
    }
    arr.push(str);
};

//保存
fs.writeFileSync(path.resolve(__dirname, ".keys"), JSON.stringify(arr));

console.log("key生成成功");

我们创建1024个key,每个key由32个uuid组成,并且我们通过repalce将uuid的短横线去掉了。

然后我们保存到一个数组里面。

接着使用原生模块fs将文件保存在本地,writeFileSync是一个同步操作,注意,他是一个同步操作,不是一个异步的。

我们再通过path来创建一个相对地址拼接,其中__dirname的关键词他的意思是相对于当前运行的js文件路径,此时我要存到当前路径,我们只需要加个文件名就行了,最后生成了fs需要的第一个参数。

第二个参数就将数组json化传入即可,然后我们可以得到一个1024的文件。

我们给文件名取名.keys,用点的话,在linux里面,默认是隐藏的,也不能说很安全,但是也是一个方式吧。

使用keys

keys创建好后,我们可以在server.js中使用,先通过fs模块读取这个文件,首先要说明一点,我们肯定是需要在keys完全读取后才能运行服务,所有不需要使用异步读取文件。

const Koa = require("koa");
const static = require("koa-static");
const body = require("koa-better-body");
const convert = require("koa-convert");
const Router = require("koa-router");
const path = require("path");
const fs = require("promise-fs");

const server = new Koa();
try {
    server.keys = JSON.parse(fs.readFileSync(path.resolve(__dirname, "keys/.keys")).toString());
} catch (e) {
    console.log("keys读取失败,请查看是否创建");
    return;
}



server.use(convert(body({
    uploadDir: path.resolve(__dirname, "upload")
})))

const router = new Router();
// server.keys = ["aaaa", "bbbb", "cccc"];
router.get("/", async ctx => {
    console.log(ctx.cookies.get("name", {
        signed: true
    }))
})




server.use(router.routes());


server.use(static("./static", {
    // maxage: 30 * 24 * 60 * 60 * 1000,  //30天缓存周期
    index: "index.html" //默认文件
}))
server.listen(8080);

由于我们需要先加载keys,所以,监听端口要放在最后,然后我们还要给fs判断,如果报错了,说明key文件不存在或者其他,我们要停止运行这个服务。

cookie的其他设置

  1. maxAge: 有效期(ms)
  2. signed: true/false 签名
  3. path: cookie路径,能向下访问,不能向上,一般没要求给根路径/,不然默认当前路径
  4. domain: 域名,限制域名访问,一般的给根域名,省事
  5. secure:true/false https访问
  6. httpOnly: 只能通过http访问,只有服务器能访问,前台js不能访问

这些都是ctx.cookies.set(key,value,{设置})的设置参数。

session

我们需要安装koa-session插件

npm i koa-session

然后我们使用

const Koa = require("koa");
const static = require("koa-static");
const Router = require("koa-router");
const path = require("path");
const fs = require("promise-fs");
const session = require("koa-session");

const server = new Koa();
try {
    server.keys = JSON.parse(fs.readFileSync(path.resolve(__dirname, "keys/.keys")).toString());
} catch (e) {
    console.log("keys读取失败,请查看是否创建");
    return;
}

server.use(session({
    maxAge: 20 * 60 * 1000,
    renew: true
}, server));


server.use(router.routes());


server.use(static("./static", {
    // maxage: 30 * 24 * 60 * 60 * 1000,  //30天缓存周期
    index: "index.html" //默认文件
}));
server.listen(8080);

也是通过中间件的方式激活,但是这在之前,session也要和cookie一样使用keys加密,所有在激活之前,我们还需要调用keys文件并赋值给server.keys属性。

调用的时候,第一个参数为配置,第二个为server对象,因为他要对server对象进行操作,server对象就是new Koa()的那个对象。

然后就是设置sessio了

给用户设置session

上面配置完毕后,后端直接给每个浏览器配置一个session,我们在后端直接操作session的内容,不需要考虑怎么配置,怎么读取,怎么设置。

直接同ctx对象的session属性,然后他本身可以理解为一个json对象,所以也是键值对的方式存储。

router.get("/", async ctx => {
    if (ctx.session["view"]) {
        ctx.session["view"]++;
    } else {
        ctx.session["view"] = 1;
    }

    ctx.body = `第${ctx.session["view"]}次访问`;

});

我们就直接设置对应的session属性就行了。

当用户超过20分钟没有进行请求的时候,session就会到期,再次请求时,属性就会清除,一切又从0开始。

session的一些配置

  1. key 自定义cookie中存储session id的key名,默认是koa:sess
  2. maxAge 过期日期,单位ms,默认1天
  3. autoCommit 自动提交头信息,默认true,不用管
  4. overwrite 自动覆盖, 默认true,默认就行了
  5. httpOnly 和那个cookie的一样,默认true,开启后客户端无法通过js修改cookie,但是浏览器本身的设置还是可以的
  6. signed 签名保护,默认true,必须要,也就是为什么开头要配置server.keys的原因
  7. rolling 每次访问都要更换session id,默认 false,用的话会影响一些服务器性能,没啥必要开
  8. rennew 默认false,一般开,session自动延期。

这些配置都是写在session()第一个参数对象里面的。

分类: Node 标签: cookienodekoasessionkoa-session

评论

暂无评论数据

暂无评论数据

目录