本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,博客地址為http://www.cnblogs.com/jasonnode/ 。學習網站上有對應每一小節的在線練習大家可以去試試。
Cookie
在web應用中,多個請求之間共享“用戶會話”是非常必要的。但HTTP1.0協議是無狀態的。那這時Cookie就出現了。那Cookie又是如何處理的呢?
Cookie的處理:
服務端向客戶端發送Cookie 客戶端的瀏覽器把Cookie保存 然后在每次請求瀏覽器都會將Cookie發送到服務端 在HTML文檔被發送之前,Web服務器通過傳送HTTP 包頭中的Set-Cookie 消息把一個cookie 發送到用戶的瀏覽器中,如下示例:
Set-Cookie: name=value; Path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT;
其中比較重要的屬性:
- name=value:鍵值對,可以設置要保存的 Key/Value,注意這里的 name 不能和其他屬性項的名字一樣
- Expires: 過期時間(秒),在設置的某個時間點后該 Cookie 就會失效,如 expires=Wednesday, 09-Nov-99 23:12:40 GMT
- maxAge: 最大失效時間(毫秒),設置在多少后失效
- secure: 當 secure 值為 true 時,cookie 在 HTTP 中是無效,在 HTTPS 中才有效
- Path: 表示 cookie 影響到的路,如 path=/。如果路徑不能匹配時,瀏覽器則不發送這個Cookie
- httpOnly:是微軟對COOKIE做的擴展。如果在COOKIE中設置了“httpOnly”屬性,則通過程序(JS腳本、applet等)將無法讀取到COOKIE信息,防止XSS攻擊產生
Node.js中的Cookie
node.js是如何想客戶端發送cookie的呢? 有兩個中方案:
使用response.writeHead,代碼如下:
//設置過期時間為一分鍾 var today = new Date(); var time = today.getTime() + 60*1000; var time2 = new Date(time); var timeObj = time2.toGMTString(); response.writeHead({ 'Set-Cookie':'myCookie="type=ninja", "language=javascript";path="/"; Expires='+timeObj+';httpOnly=true' });
缺點:使用response.writeHead只能發送一次頭部,即只能調用一次,且不能與response.render共存,否則會報錯。
使用response.cookie,代碼示例如下:
response.cookie('haha', 'name1=value1&name2=value2', { maxAge:10*1000, path:'/', httpOnly:true });
語法: response.cookie('cookieName’, 'name=value[name=value…]',[options]);
options 每個字段的意思在上文中都講解了,這里不再重復闡述了。
Cookie的簡單使用
express 在 4.x 版本之后,管理session和cookies等許多模塊都不再直接包含在express中, `而是需要單獨下載安裝相應模塊。
cookieParser安裝:
$ npm install cookie-parser
使用方法:
var express = require('express'); var cookieParser = require('cookie-parser'); var app = express(); app.use(cookieParser()); app.get('/', function (req, res) { // 檢查 session 中的 isVisit 字段是否存在 // 如果存在則增加一次,否則為 session 設置 isVisit 字段,並初始化為 1。 if (req.cookie.isVisit) { req.cookie.isVisit++; res.send('<p>第 ' + req.cookie.isVisit + '次來此頁面</p>'); } else { req.cookie.isVisit = 1; res.send("歡迎第一次來這里"); console.log("Cookies: ", req.cookies); //打印cookie } }); app.listen(80);
什么是Session?
session是另一種記錄客戶狀態的機制,不同的是Cookie保存在客戶端瀏覽器中,而session保存在服務器上。
客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上,這就是session。客戶端瀏覽器再次訪問時只需要從該Session中查找該客戶的狀態就可以了。
如果說Cookie機制是通過檢查客戶身上的“通行證”來確定客戶身份的話,那么session機制就是通過檢查服務器上的“客戶明細表”來確認客戶身份。
session相當於程序在服務器上建立的一份客戶檔案,客戶來訪的時候只需要查詢客戶檔案表就可以了。
兩者的區別:
- cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
- cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙 考慮到安全應當使用session。
- session會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能 考慮到減輕服務器性能方面,應當使用COOKIE。
- 單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
所以建議:將登陸信息等重要信息存放為session、其他信息如果需要保留,可以放在cookie中
Session的簡單應用
跟cookie一樣都需要單獨的安裝和引用模塊, 安裝模塊:$sudo npm install express-session 主要的方法就是 session(options),其中 options 中包含可選參數,主要有:
- name: 設置 cookie 中,保存 session 的字段名稱,默認為 connect.sid 。
- store: session 的存儲方式,默認存放在內存中,也可以使用 redis,mongodb 等。express 生態中都有相應模塊的支持。
- secret: 通過設置的 secret 字符串,來計算 hash 值並放在 cookie 中,使產生的 signedCookie 防篡改。
- cookie: 設置存放 session id 的 cookie 的相關選項,默認為 (default: { path: '/’, httpOnly: true, secure: false, maxAge: null })
- genid: 產生一個新的 session_id 時,所使用的函數, 默認使用 uid2 這個 npm 包。
- rolling: 每個請求都重新設置一個 cookie,默認為 false。
- resave: 即使 session 沒有被修改,也保存 session 值,默認為 true。
示例:
var express = require('express'); var session = resuire('session'); var app = exoress(); app.user(session({ secret: 'hubwiz app', //secret的值建議使用隨機字符串 cookie: {maxAge: 60 * 1000 * 30} // 過期時間(毫秒) })); app.get('/', function (req, res) { if (req.session.sign) {//檢查用戶是否已經登錄 console.log(req.session);//打印session的值 res.send('welecome <strong>' + req.session.name + '</strong>, 歡迎你再次登錄'); } else {//否則展示index頁面 req.session.sign = true; req.session.name = '匯智網'; res.end('歡迎登陸!'); } }); app.listen(80);