UNPKG

titbit-toolkit

Version:

titbit框架的工具集,包括跨域、静态资源处理,权限过滤,请求计时,cookie,session,jwt等大量中间件

175 lines (131 loc) 3.95 kB
'use strict' const fs = require('node:fs') const crypto = require('node:crypto') /* 这个模块用于titbit框架的登录会话,调用一定要在cookie中间件之后。 整体的过程就是在基于cookie中间件的解析结果,如果检测到cookie中有会话ID 则寻找文件并读取数据,解析成JSON对象添加到c.session;如果cookie中 没有会话ID或者读取文件失败则创建会话文件并发送Set-Cookie头部信息保存会话ID。 */ class Session { constructor() { this.expires = false this.domain = false this.path = '/' this.sessionDir = '/tmp' this.ds = '/' if (process.platform.indexOf('win') === 0) { this.ds = '\\' this.sessionDir = 'C:\\Users\\Public\\sess' try { fs.accessSync(this.sessionDir) } catch (err) { fs.mkdirSync(this.sessionDir) } } this.prefix = 'titbit_sess_' this.sessionKey = 'TITBIT_SESSID' this.error = null } init(app) { let proto = app.httpServ.Content.prototype let self = this proto.sessionError = function (options={}) { let err = self.error if (options.clear) self.error = null return err } proto.setSession = function (key, data) { this._session[key] = data this._sessionState = true } proto.getSession = function (key = null) { if (key === null) { return this._session } return this._session[key] || null } proto.deleteSession = function (key) { delete this._session[key] this._sessionState = true } proto.clearSession = function () { this._sessionState = false this._session = {} fs.unlink(this._sessFile, (err) => { err && (self.error = err) }) } } mid() { let self = this return async (c, next) => { c._session = {} c._sessionState = false c._sessFile = '' let sess_file = '' let sessid = c.cookie[ self.sessionKey ] let sess_state if (sessid) { sess_file = `${self.sessionDir}${self.ds}${self.prefix}${sessid}` c._sessFile = sess_file await new Promise((rv, rj) => { fs.readFile(sess_file, (err, data) => { if (err) { rj(err) } else { sess_state = true rv(data) } }) }).then(data => { c._session = JSON.parse(data) }, err => { sess_state = false }).catch(err => { self.error = err }) } if (sessid === undefined || sess_state === false) { let org_name = `${c.host}_${Date.now()}__${Math.random()}` let hash = crypto.createHash('sha1') hash.update(org_name) sessid = hash.digest('hex') sess_file = self.prefix + sessid let set_cookie = `${self.sessionKey}=${sessid};` if (self.expires) { var t = new Date(Date.now() + self.expires * 1000) set_cookie += `Expires=${t.toString()};` } set_cookie += `Path=${self.path};` if (self.domain) { set_cookie += `Domain=${self.domain}` } let session_path_file = `${self.sessionDir}/${sess_file}` c._sessFile = session_path_file await new Promise((rv, rj) => { fs.writeFile(session_path_file, '{}', err => { if (err) { rj(err) } else { rv(true) } }) }).then(data => { c.setHeader('set-cookie', set_cookie) }, err => { self.error = err }) } await next() if (c._sessionState) { let tmpText = JSON.stringify(c._session) fs.writeFile(c._sessFile, tmpText, (err) => { self.error = err }) } c._session = null } } } module.exports = Session