热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:koasession源码学习——session处理流程

本文由编程笔记#小编为大家整理,主要介绍了koa-session源码学习——session处理流程相关的知识,希望对你有一定的参考价值。上一篇文章中,我们以ctx.session.vie
本文由编程笔记#小编为大家整理,主要介绍了koa-session源码学习——session处理流程相关的知识,希望对你有一定的参考价值。

上一篇文章中,我们以ctx.session.views=2 这一行代码为线索,探讨了示例代码以及koa-session源码的整体执行流程,sess.session为追踪重点,今天我们进一步完善源码中关于session的处理流程。

我们接着上篇的内容向下进行,上一篇中的this.session打印如下:

Session {_sessCtx: ContextSession, _ctx: Object, isNew: true, views: 2}

 

我们从Index.js的 commit()方法说起:

return async function session(ctx, next) {
const sess
= ctx[CONTEXT_SESSION];
if (sess.store) await sess.initFromExternal();
try {
await next();
}
catch (err) {
throw err;
}
finally {
if (opts.autoCommit) {
await sess.commit();
}
}
};

sess.commit()调用的是 ContextSession 里的commit方法,首先来看该方法的开头部分:

const session = this.session;
const opts
= this.opts;
const ctx
= this.ctx;

我们将这里的session打印出来,结果如下:

Session {_sessCtx: ContextSession, _ctx: Object, isNew: true, views: 2}

发现到这里还没有加密,我们继续向下看,_shouldSaveSession()方法里的:

const json = session.toJSON();

此时打印出json:

Object {views: 2}

可以看到上面的session只剩下了views属性,来看看.JSON()方法的代码:

toJSON() {
const obj
= {};
Object.keys(
this).forEach(key => {
if (key === ‘isNew‘) return;
if (key[0] === ‘_‘) return; //key[0]代表key的第一位
obj[key] = this[key];
});
return obj;
}

可以理解,是将session里的 isNew属性 和 以‘_’开头的属性都去掉了。

 

继续看_shouldSaveSession()方法里的:

const changed = prevHash !== util.hash(json);
if (changed) return ‘changed‘;

prevHash为create()方法里生成的,假设我们是第一次执行ctx.session.views=2,ctx.COOKIEs.get 为空,因此这里的 prevHash为undefined,我们再将util.hash(json),打印出来,查看一下:

552152158

你会发现原来的json,由Object {views: 2}变为了552152158。 因此这段代码返回的是 ‘changed’

 

我们来看util.hash()方法:

hash(sess) {
return crc(JSON.stringify(sess));
},

很简单的代码!用的crc插件进行处理,其中JSON.stringify(sess)的作用是,将json从 Object {views: 2} 变为:{"views":2},由object格式变为了JSON格式。

 

最后到save()方法,先将待保存的session对象,添加了_expire属性和_maxAge属性:

// set expire for check
json._expire = maxAge + Date.now();
json._maxAge
= maxAge;

我们再将json打印出来:

Object {views: 2, _expire: 1592550308718, _maxAge: 86400000}

 

然后对整个json也就是session进行base64编码加密:

json = opts.encode(json);

加密后的json再次打印出来为:

eyJ2aWV3cyI6MiwiX2V4cGlyZSI6MTU5MjU1MDM3MjI0MiwiX21heEFnZSI6ODY0MDAwMDB9

 

此时在因特网上传输起来,已经具有了一定得保密性。

 

base64编码方法如下:

encode(body) {
body
= JSON.stringify(body);
return Buffer.from(body).toString(‘base64‘); //base64编码实际是对二进制数进行编码,Buffer.from()为Node.js处理二进制数据时使用。
}

 

对应的base64解码方法:

decode(string) {
let json
= Buffer.from(string,‘base64‘).toString(‘utf-8‘);
json
= JSON.parse(json);
return json;
}

 

最后将base64编码的json,保存到COOKIE中:

this.ctx.COOKIEs.set(key, json, opts);

 

由此我们可以看到,session实际上是以COOKIE 的形式保存的。

 

如果文章中有不正确的地方,欢迎大家交流指正。

 


推荐阅读
  • 本地存储组件实现对IE低版本浏览器的兼容性支持 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文将介绍如何在混合开发(Hybrid)应用中实现Native与HTML5的交互,包括基本概念、学习目标以及具体的实现步骤。 ... [详细]
  • 一个建表一个执行crud操作建表代码importandroid.content.Context;importandroid.database.sqlite.SQLiteDat ... [详细]
  • 用阿里云的免费 SSL 证书让网站从 HTTP 换成 HTTPS
    HTTP协议是不加密传输数据的,也就是用户跟你的网站之间传递数据有可能在途中被截获,破解传递的真实内容,所以使用不加密的HTTP的网站是不 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 在 Vue 应用开发中,页面状态管理和跨页面数据传递是常见需求。本文将详细介绍 Vue Router 提供的两种有效方式,帮助开发者高效地实现页面间的数据交互与状态同步,同时分享一些最佳实践和注意事项。 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
  • 在Kohana 3框架中,实现最优的即时消息显示方法是许多开发者关注的问题。本文将探讨如何高效、优雅地展示flash消息,包括最佳实践和技术细节,以提升用户体验和代码可维护性。 ... [详细]
  • Python 实战:异步爬虫(协程技术)与分布式爬虫(多进程应用)深入解析
    本文将深入探讨 Python 异步爬虫和分布式爬虫的技术细节,重点介绍协程技术和多进程应用在爬虫开发中的实际应用。通过对比多进程和协程的工作原理,帮助读者理解两者在性能和资源利用上的差异,从而在实际项目中做出更合适的选择。文章还将结合具体案例,展示如何高效地实现异步和分布式爬虫,以提升数据抓取的效率和稳定性。 ... [详细]
  • 本指南介绍了 `requests` 库的基本使用方法,详细解释了其七个主要函数。其中,`requests.request()` 是构建请求的基础方法,支持其他高级功能的实现。此外,我们还重点介绍了如何使用 `requests.get()` 方法来获取 HTML 网页内容,这是进行网页数据抓取和解析的重要步骤。通过这些基础方法,读者可以轻松上手并掌握网页数据抓取的核心技巧。 ... [详细]
  • 本文介绍了一种利用PHP cURL库高效提取Sohu邮箱联系人列表的方法。通过设置错误报告级别、定义Cookie文件路径等关键步骤,确保了代码的稳定性和可靠性。经过实际测试,该方法在2012年3月24日被验证为有效,能够快速准确地获取联系人信息。此外,文章还提供了详细的代码示例和注意事项,帮助开发者更好地理解和应用这一技术。 ... [详细]
author-avatar
momosu1028_738_636
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有