我转过几个弯 绕过那个小雨楼
拿着蒲扇摆着衣衫渡着紧箍咒
不问天涯不停留 喝过几壶酒
不过年少白头道义放胸口
倘若明天之后 遥看前尘剑封侯
似那天上神仙无所求
朝朝暮暮君如梦醒十分不为何理由
是真是假是惶恐是无休
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
又过了几个弯 算尽天量道莫慌
踏这田园闻这芳草香
跌跌撞撞仗剑天涯折煞不枉无笔良
是梦是幻是温柔是家乡
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
谁能与我一醉方休
koa框架20 cookie、session
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的其他设置
- maxAge: 有效期(ms)
- signed: true/false 签名
- path: cookie路径,能向下访问,不能向上,一般没要求给根路径
/
,不然默认当前路径 - domain: 域名,限制域名访问,一般的给根域名,省事
- secure:true/false https访问
- 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的一些配置
- key 自定义cookie中存储session id的key名,默认是koa:sess
- maxAge 过期日期,单位ms,默认1天
- autoCommit 自动提交头信息,默认true,不用管
- overwrite 自动覆盖, 默认true,默认就行了
- httpOnly 和那个cookie的一样,默认true,开启后客户端无法通过js修改cookie,但是浏览器本身的设置还是可以的
- signed 签名保护,默认true,必须要,也就是为什么开头要配置server.keys的原因
- rolling 每次访问都要更换session id,默认 false,用的话会影响一些服务器性能,没啥必要开
- rennew 默认false,一般开,session自动延期。
这些配置都是写在session()第一个参数对象里面的。
评论(0)