您好,登錄后才能下訂單哦!
小編給大家分享一下nodejs中cookie和session的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
用慣了框架中的插件,最近在重溫node基礎模塊時也不禁在想:什么是Cookie?什么是Session?兩者的區別和聯系有哪些?Node.js是否提供了相應的模塊來管理存儲Session?如果沒有提供相應模塊,我們應該如何實現一個類似Session管理的模塊呢
Session和Cookie都是基于Web服務器的,不同的是Cookie存儲在客戶端,而Session存儲在服務器端。
當用戶在瀏覽網站的時候,Web服務器會在瀏覽器上存儲一些當前用戶的相關信息,而在本地Web客戶端存儲的就是Cookie數據。這樣當下次用戶再瀏覽同一個網站時,Web服務器就會先查看并讀取本地的cookie資料,如果有cookie就會依據cookie里面的內容并判斷其過期時間,從而給用戶特殊的數據返回。
cookie的使用很普遍 —— 許多支持個性化服務的網站,大多都是用cookie來辨認使用者,以方便送出為使用者量身定做的內容,像web接口的免費email。再比如:大多網站支持的“7天免登錄”。
具體來說,cookie機制采用的是在客戶端保持狀態的方案,而session機制采用的是在服務器端保持狀態的方案。同時我們也可以看到:由于服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助于cookie機制來達到保存標識的目的。但實際上它還有其他選擇。正統的cookie分發是通過擴展HTTP協議來達到的,服務器通過在http的響應頭上加上一行特殊的標識,以提示瀏覽器按照指示生成相應的cookie。然而,純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie —— document.cookie='xxx=xxx; expires=xxx'
。
cookie是基于session的
cookie的使用卻是由瀏覽器按照一定的原則在后臺自動發送給服務器的。瀏覽器檢查所有存儲的cookie,如果某個cookie所聲明的作用范圍大于等于將要請求的資源所在的位置,則可把該cookie附在去請求資源的http請求頭上發送給服務器。
Cookie的內容主要包括:名字、值、過期時間、路徑和域。路徑與域一起構成Cookie的作用范圍。若不設置過期時間,則表示這個Cookie的生命期為瀏覽器會話期間,關閉瀏覽器窗口,Cookie 就消失。這種生命期為瀏覽器會話期的Cookie,被稱為會話Cookie。會話Cookie一般不存儲在硬盤上,而是保存在內存里,當然這種行為并不是規范的。若設置了過期時間,瀏覽器就會把Cookie保存到硬盤上,關閉后再次打開瀏覽器,這些Cookie仍然有效,直到超過設定的過期時間。
而對于保存在內存里的Cookie, 不同的瀏覽器有不同的處理方式。Session機制是一種服務器端的機制,服務器使用類似于散列表的結構(也可能真的使用散列表)來保存信息。當程序需要為某個客戶端的請求創建一個 Session 時,服務器首先檢查這個客戶端的請求里是否已包含了一個Session標識(稱為Session id),如果已包含則說明以前已經為此客戶端創建過Session,服務器就按照Session id把這個Session檢索出來使用(檢索不到,會新建一個), 如果客戶端請求不包含Session id,則為此客戶端創建一個Session并且生成-一個與此Session相關聯的Session id, Session id的值應該是一個既不會重復,又不容易被發現其生成規律的字符串,這個Session id將在本次響應中被返回給客戶端保存。保存這個Session id的方式可以采用Cookie,這樣在交互過程中瀏覽器可以自動按照規則把這個標識發送給服務器。一般這個Cookie的名字都類似于SESSID。
既然session如此“重要”,我們不妨來看看session模塊:
PHP中內置了session方法可供調用,例如session_start
以及$_SESSION
等。但是原生的Node.js中卻沒有提供任何session管理的模塊,因此我們可以自己實現一個:
根據上面對session和cookie的介紹,我們不難得出其中的邏輯
(其實,服務端檢查的是session在瀏覽器的cookie中有沒有對應的session id)
如上圖所示,客戶端首先會請求Session,而當服務端檢查客戶端中的Cookie沒有相應的Session id時,會通過-一定方式為其生成一個新的Session id, 而如果Cookie中存在該Session id并且沒有過期時,則直接返回Session數據。
那么根據如上流程示意圖以及介紹,可以為我們需要實現的模塊先創建3種方法,分別是start、 newSession和cleanSessions。 start方法主要是啟動Session管理,newSession主要是為客戶端創建一個新的Session id, 而cleanSessions則是清除Session數據。
本模塊應用一個Session數組來存儲系統所有的Session, 當有Session id存在時,無需新建Sessionid,而是直接讀取返回Session數據;而當Sessionid不存在時,需要創建Session id,并且將Sessionid存儲在該客戶端的Cookie中。筆者做了一個簡單的session校驗start,代碼如下:
var start = function(req,res){ var conn = { res: res, req: req }; var cookies = {}; if(typeof conn.req.headers.cookie !== "undefined"){ //session存在時,對session進行解析,獲取其中的session id conn.req.headers.cookie.split(';').forEach(function(cookie){ var parts=cookie.split('='); cookies[ parts[0].trim() ] = (parts[1] || '').trim(); }); }else{ cookies.SESSID = 0; } var SESSID = cookies.SESSID; if(typeof sessions[SESSID] !== "undefined"){ //判斷服務器中是否存在該session值 session=sessions[SESSID]; if(session.expires < Date()){ //如果session過期 delete sessions[SESSID]; //session過期或者不存在(下面那個)時,新生成一個session return newSession(conn.res); }else{ var dt = new Date(); dt.setMinutes(dt.getMinutes() + 30); session.expires = dt; //重置session過期時間 return sessions[SESSID]; } }else{ return newSession(conn.res); } };
以上就是一個session簡單的校驗過程,主要思路就是通過req對象中的headers獲取cookie,并對cookie進行解析獲取session id,進而判斷是否存在該id值,從而返回或生成新的session。下面我們來看下主要方法newSession的實現:
function newSession(res){ var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; var SESSID = ''; for(var i = 0; i < 40; i++){ var rnum = Math.floor(Math.random()*chars.length); SESSID += chars.substring(rnum,rnum+1); } if(typeof sessions[SESSID] !== "undefined"){ return newSession(res); //避免重復session } var dt = new Date(); dt.setMinutes(dt.getMinutes() + 30); var session = { SESSID, expires: dt }; sessions[SESSID] = session; //為客戶端新增cookie數據(在客戶端cookie中保存sessid) res.setHeader('Set-Cookie','SESSID=' + SESSID); return session; }
當然,最后就是將整個模塊暴露出去:
exports.start=start;
Session模塊的應用
我們可以在入口文件(例如app.js)中require該模塊,并在HTTP的createServer函數中調用session.start,并將session.start返回的對象作為一個全局對象存儲,代碼如下:
var app=http.createServer(function(req,res){ global.sessionLib = session.start(res,req); }); //調用時 if(!sessionLib['username']){ sessionLib['username'] = 'mxc'; }
介紹完基礎模塊,拿筆者的一個項目來說下框架中相關插件的基本用法 —— 其實其實現原理與本文所說不差一二。
const cookieSession=require('cookie-session');
(function (){ var keys=[]; for(var i=0;i<100000;i++){ keys[i]='a_'+Math.random(); } server.use(cookieSession({ name: 'sess_id', keys: keys, maxAge: 20*60*1000 //20min })); })();
使用時判斷:
//檢查登錄狀態 router.use((req, res, next)=>{ if(!req.session['admin_id'] && req.url!='/login'){ //沒有登錄且當前不是登錄頁(避免redirect黑洞) res.redirect('/admin/login'); }else{ next(); } });
登錄后:
req.session['admin_id']=data[0].ID;
以上是“nodejs中cookie和session的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。