從koa session2看session機制實現

2021-09-11 13:25:45 字數 3349 閱讀 5787

session機制通常是用來做記住使用者登入資訊的,借助cookie,從而實現使用者登入首席資訊官時間的儲存。即使是使用者瀏覽器關閉後又重新開啟,只要cookie還在,就不用重新登入。

const session = require("koa-session2")

const mongostore = require("koa-session2-mongo")

store: new mongostore(),

maxage: 24 * 60 * 60 * 1000

// one day

}))複製**

const store = require('./libs/store.js');

module.exports = (opts = {}) => = opts;

return async (ctx, next) => ;

} else ;}}

const old = json.stringify(ctx.session);

await next();

// if not changed

if(old == json.stringify(ctx.session)) return;

// if is an empty object

if(ctx.session instanceof object && !object.keys(ctx.session).length)

// need clear old session

if(id && !ctx.session)

// set/update session

const sid = await store.set(ctx.session, object.assign({}, opts, ), ctx);

ctx.cookies.set(key, sid, opts);

}}// reeexport store to not use reference to internal files

module.exports.store = store;

複製**

首先作為乙個中介軟體,執行後應該返回乙個async函式,這個async函式會接收到ctx和next物件。

當請求到來並執行到本中介軟體時,首先會根據我們設定的key從cookie獲取對應的值:

session()

複製**

此處的key設定為koa-sess,因此執行let id = ctx.cookies.get(key, opts)的時候我們就獲取到了cookie中儲存的值,也就是這裡的id。

如果id不存在,令ctx.session = {}等於空物件。如果id存在的話,從store中找到本id對應的session物件。可以認為此處的store就是乙個用於儲存資料的物件。一條完整的session物件如下

,

"lastaccess" : isodate("2018-01-25t06:57:06.413+0000")

}複製**

物件中的sid就是我們從cookie中獲取到的那個id。這樣cookie中只存id,而真正的使用者資訊存在store中,避免了cookie遭破解使用者資訊洩露。

然後將session物件賦給ctx.session,然後await next()執行後面的中介軟體。當其他中介軟體執行完畢後,比較ctx.session物件時候發生改變(如controller中是否增刪改了某些值)。如果ctx.session沒有變化直接return不再處理。如果id不存在並且ctx.session不是空物件,那麼建立一條新的session記錄,然後將建立的記錄sid通過cookie返回給瀏覽器

ctx.cookies.set(key, sid, opts);

複製**

如果id存在(說明已經建立過)但ctx.session為空物件,刪除物件的session記錄。

koa-session2中介軟體預設實現了乙個store,使用的是map物件。

const  = require('crypto');

class store

getid(length)

get(sid)

set(session, = {})

if (maxage)

try catch (err)

return sid;

}destroy(sid)

}module.exports = store;

複製**

koa-session2預設使用store的例項儲存session。

store建構函式裡this.sessions = new map()建立了乙個map物件,this.sessions就是所有sessions儲存的地方。

然後this.__timer = new map()又建立了乙個map物件,this.__timer用來儲存定時器,如果我們設定了maxage,就會開啟乙個定時器定時清除session記錄。

接下來get方法:

get(sid) 

複製**

很簡單,如果this.sessions有sid對應的值,返回,如果沒有返回undefined。

接下來set方法:

set(session,  = {}) 

if (maxage)

try catch (err)

return sid;

}複製**

如果沒有sid(建立而不是更新session),新建乙個24位長的字串作為sid。如果sessions和__timer中都存有sid的記錄,先清除__timer中儲存的定時器。如果maxage存在的話,新建乙個定時器定時刪除session。最後用sid和ctx.session中儲存的物件 新建或更新map記錄。

最後destroy方法:

destroy(sid) 

複製**

清除sessions和__timer中的session記錄

預設的store在記憶體中儲存session資料,如果伺服器重啟將會丟失掉。

如果使用者量大將會爆記憶體。

koa-session2-mongo中介軟體的實現思路與預設store相同,只不過是將資料存到了資料庫裡。使用mongo儲存session資訊。避免了重啟和爆記憶體問題。

koa-session2中介軟體已經能夠實現基本的session儲存。

如果需要功能更加強大的中介軟體,推薦koa官方的koa-session,當然如果想要存到mongo裡,可以使用koa-session-mongo2這個中介軟體。

從Yii2的Request看其CSRF防範策略

先畫一幅流程圖理理思路 結果呢,無論是用測試工具postman還是用命令列curl請求總是會得到http400 bad request的錯誤 而如果用web網頁方式get訪問 去除verbfilter的post限制 是正常的 通過帖子下面的帖子找到了問題的所在,是csrf驗證的原因 因為web網頁訪...

從Yii2的Request看其CSRF防範策略

用ajax請求還是用命令列curl請求總是會得到http400 bad request的錯誤,而如果用web網頁方式get訪問 去除verbfilter的post限制 是正常的,是csrf驗證的原因 因為web網頁訪問的時候form表單中會有對應的乙個隱藏input csrf進行了驗證才可以正常進行...

從《鋼鐵俠2》看軟體測試的重要性

作為程式設計師的我,昨晚看完鋼鐵俠2,一路回來是感嘆頗多。印象最深的還是片尾處,反派被擊倒後,開始了自爆程式,然而此自爆程式的倒計時部分卻存在明顯的bug,導致主角不但成功逃走甚至還有時間營救幾公里開外的女友。更可恨的是,主角不但成功避開自爆,而且還和女友在樓頂邊啃嘴邊看自爆產生的烟花。這對對手是多...