Node.js中Koa2如何使用Session完成登陆状态保持?

项目要用到登陆注册,就须要使用到Cookie和Session来保持登陆状态,因而就简单研究了一下

Cookie和Session的工做原理

前面已经专门发过一篇帖子记录Cookie和Session的工做原理了,不明白的小伙伴能够看看Cookie、Session是如何保持登陆状态的?数据库

使用Koa的Session中间件

Koa是一个简洁的框架,把许多小功能都拆分红了中间件,用一个洋葱模型保证了中间件丰富的可拓展性,咱们要使用Session来保持登陆状态,就须要引用Session中间件。npm

安装Koa-Session中间件

npm install koa-session --save

若是须要使用TypeScript进行开发,则须要引入对应的TS类型声明segmentfault

npm install @types/koa-session --save

配置Session

Koa-Session须要作一些配置:安全

const session_signed_key = ["some secret hurr"];  // 这个是配合signed属性的签名key
const session_config = {
    key: 'koa:sess', /**  cookie的key。 (默认是 koa:sess) */
    maxAge: 4000,   /**  session 过时时间,以毫秒ms为单位计算 。*/
    autoCommit: true, /** 自动提交到响应头。(默认是 true) */
    overwrite: true, /** 是否容许重写 。(默认是 true) */
    httpOnly: true, /** 是否设置HttpOnly,若是在Cookie中设置了"HttpOnly"属性,那么经过程序(JS脚本、Applet等)将没法读取到Cookie信息,这样能有效的防止XSS攻击。  (默认 true) */
    signed: true, /** 是否签名。(默认是 true) */
    rolling: true, /** 是否每次响应时刷新Session的有效期。(默认是 false) */
    renew: false, /** 是否在Session快过时时刷新Session的有效期。(默认是 false) */
};

咱们须要关注这几个配置:cookie

  • renew rolling

这两个均可以在用户访问的过程当中刷新有效期,不至于让用户访问过程当中Session过时成为未登陆状态session

  • signed

这个是对客户端Cookie的签名,也就是用一个特色的字符加密,保证客户端Cookie不会被伪造出来app

  • httpOnly

打开这个使得经过程序(JS脚本、Applet等)没法读取Cookie,大大提升了安全性框架

  • maxAge

以ms为单位的过时时间koa

简单的使用

首先理一下思路post

  1. 判断访问者的Session有没有过登陆记录属性
  2. 若是有且值为true,则为已登陆,不然为未登陆
  3. 若是为已登陆,则不执行判断,直接返回已登陆,若是为未登陆,则执行下一步登陆验证
  4. 若是验证成功,则返回的登陆成功,而且在它的session中记下登陆属性为true,若是验证失败,则返回登陆失败。
为了测试方便,如下用Get请求和一个固定的帐号密码代替数据库查询,实际开发应该使用POST和数据库比对。同时为了测试方便,将过时时间设置为4000ms,便于快速看到Cookies过时,实际开发应该设置长一些,好比几小时甚至几天,取决于业务需求。
const Koa = require('koa');                               // 导入Koa
const Koa_Session = require('koa-session');   // 导入koa-session     
// 配置
const session_signed_key = ["some secret hurr"];  // 这个是配合signed属性的签名key
const session_config = {
    key: 'koa:sess', /**  cookie的key。 (默认是 koa:sess) */
    maxAge: 4000,   /**  session 过时时间,以毫秒ms为单位计算 。*/
    autoCommit: true, /** 自动提交到响应头。(默认是 true) */
    overwrite: true, /** 是否容许重写 。(默认是 true) */
    httpOnly: true, /** 是否设置HttpOnly,若是在Cookie中设置了"HttpOnly"属性,那么经过程序(JS脚本、Applet等)将没法读取到Cookie信息,这样能有效的防止XSS攻击。  (默认 true) */
    signed: true, /** 是否签名。(默认是 true) */
    rolling: true, /** 是否每次响应时刷新Session的有效期。(默认是 false) */
    renew: false, /** 是否在Session快过时时刷新Session的有效期。(默认是 false) */
};

// 实例化
const app = new Koa();
const session = Koa_Session(session_config, app)
app.keys = session_signed_key;

// 使用中间件,注意有前后顺序
app.use(session);

app.use(ctx => {
    const databaseUserName = "testSession";
    const databaseUserPasswd = "noDatabaseTest";
    // 对/favicon.ico网站图标请求忽略
    if (ctx.path === '/favicon.ico') return;

    if (!ctx.session.logged) {  // 若是登陆属性为undefined或者false,对应未登陆和登陆失败
        // 设置登陆属性为false
        ctx.session.logged = false;

        // 取请求url解析后的参数对象,方便比对
        // 如?nickname=post修改&passwd=123解析为{nickname:"post修改",passwd:"123"}
        let query = ctx.request.query;

        // 判断用户名密码是否为空
        if (query.nickname && query.passwd) {

            // 比对并分状况返回结果  
            if (databaseUserName == query.nickname) {  // 若是存在该用户名

                // 进行密码比对并返回结果 
                ctx.body = (databaseUserPasswd == query.passwd) ? "登陆成功" : "用户名或密码错误";
                ctx.session.logged = true;
            } else {                    // 若是不存在该用户名                                           //  若是用户名不存在
                ctx.body = "用户名不存在";
            }
        } else {
            ctx.body = "用户名密码不能为空";
        }
    } else {
        ctx.body = "已登陆";
    }

}
);

app.listen(3000);
console.log("Koa运行在:http://127.0.0.1:3000");

运行一下,控制台输出:

Koa运行在:http://127.0.0.1:3000

访问http://127.0.0.1:3000,能够看到咱们没有填写登陆参数,而后返回了用户名密码不能空,而且按下F12,点击Cookies再点击http://127.0.0.1:3000,看到了咱们的SessionId被记录到了Cookies中,说明Session生效了。
1

咱们静置一会但不刷新页面,再点击Cookies后从新点击,http://127.0.0.1:3000(刷新Cookies显示),发现咱们的SessionId不见了,说明咱们的过时时间也生效了
2

我将Cookies的数据截详细一点就是这样的,能够看到有个过时时间:
3

咱们再访问http://127.0.0.1:3000/?nickname=123http://127.0.0.1:3000/?passwd=123,都输出了
4

访问http://127.0.0.1:3000/?nickname=123&&passwd=123,输出
5

访问http://127.0.0.1:3000/?nickname=testSession&&passwd=123,输出
6

最后尝试正确的用户名密码http://127.0.0.1:3000/?nickname=testSession&&passwd=noDatabaseTest
,输出登陆成功
尝试再次访问http://127.0.0.1:3000/?nickname=testSession&&passwd=noDatabaseTest
,输出

重复登陆

在有效期限内访问别的页面http://127.0.0.1:3000/,输出
有效期内

有效期内不断刷新就能保持登陆状态
不断刷新

有效期内没有从新操做页面刷新状态就会天然过时
过时

相关文章
相关标签/搜索