項目要用到登陸註冊,就須要使用到Cookie和Session來保持登陸狀態,因而就簡單研究了一下
前面已經專門發過一篇帖子記錄Cookie和Session的工做原理了,不明白的小夥伴能夠看看Cookie、Session是如何保持登陸狀態的?。數據庫
Koa是一個簡潔的框架,把許多小功能都拆分紅了中間件,用一個洋蔥模型保證了中間件豐富的可拓展性,咱們要使用Session來保持登陸狀態,就須要引用Session中間件。npm
npm install koa-session --save
若是須要使用TypeScript進行開發,則須要引入對應的TS類型聲明segmentfault
npm install @types/koa-session --save
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
這兩個均可以在用戶訪問的過程當中刷新有效期,不至於讓用戶訪問過程當中Session過時成爲未登陸狀態session
這個是對客戶端Cookie的簽名,也就是用一個特色的字符加密,保證客戶端Cookie不會被僞造出來app
打開這個使得經過程序(JS腳本、Applet等)沒法讀取Cookie,大大提升了安全性框架
以ms爲單位的過時時間koa
首先理一下思路post
爲了測試方便,如下用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生效了。
咱們靜置一會但不刷新頁面,再點擊Cookies後從新點擊,http://127.0.0.1:3000(刷新Cookies顯示),發現咱們的SessionId不見了,說明咱們的過時時間也生效了
我將Cookies的數據截詳細一點就是這樣的,能夠看到有個過時時間:
咱們再訪問http://127.0.0.1:3000/?nickname=123和http://127.0.0.1:3000/?passwd=123,都輸出了
訪問http://127.0.0.1:3000/?nickname=123&&passwd=123,輸出
訪問http://127.0.0.1:3000/?nickname=testSession&&passwd=123,輸出
最後嘗試正確的用戶名密碼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/,輸出
有效期內不斷刷新就能保持登陸狀態
有效期內沒有從新操做頁面刷新狀態就會天然過時