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,導致主角不但成功逃走甚至還有時間營救幾公里開外的女友。更可恨的是,主角不但成功避開自爆,而且還和女友在樓頂邊啃嘴邊看自爆產生的烟花。這對對手是多...