什麼是session?javascript
session就是會話,客戶端和服務器直接的會話。他的粒度比http連接更粗,一次會話包含了屢次鏈接。即一個session是屢次http鏈接的集合。從個人客戶端鏈接到服務器到關閉客戶端,這期間的客戶端和服務器之間的聯繫就是一次會話。java
爲何須要session?數據庫
咱們知道,http是無狀態的,每一次http鏈接之間是無關聯的。就好像加入a是客戶端,b是服務器,那麼無狀態就是指a沒有記憶力,每一次a和b的對話(即每一次http鏈接),a都是記不住,a不記得本身以前是否跟b說過話,也不記得說話的內容,這就是http的無狀態。http的這個特性就致使了咱們沒法直接實現狀態登陸的保存,沒法實現當登陸帳號後鏈接該服務器其餘頁面時依舊保持着登錄的狀態。express
因此爲了解決問題,人們想出了不少方法,好比說登陸後在數據庫中對該用戶的數據打上登陸的標記,每次連接網頁就去查詢誰登陸了,可是這種辦法太笨,會形成對服務器的壓力。json
還有一種辦法是利用cookie,cookie就是一種客戶端存儲技術。咱們能夠把用戶的信息存儲在cookie中,每次切換頁面就去cookie中查詢,保持該用戶的登陸狀態。可是這種辦法有一個巨大缺陷,就是不夠安全,信息是存儲在客戶端的,有可能被其餘用戶惡意讀取篡改,因此這種辦法也不可行。安全
這時候人們就想,既然存儲在客戶端不安全,那我存在服務器不就相對安全了嗎?因此就有了session的誕生。因此總結下來,session就是一種在同一主機不一樣http請求之間保持狀態的技術手段服務器
Session的機制cookie
1.生成全局惟一標識符(sessionid);每一個客戶端對應一個id,服務器識別客戶端後經過其id讀取session中的數據session
2.開闢數據存儲空間。通常會在內存中建立相應的數據結構,但這種狀況下,系統一旦掉電,全部的會話數據就會丟失,若是是電子商務網站,這種事故會形成嚴重的後果。不過也能夠寫到文件裏甚至存儲在數據庫中,這樣雖然會增長I/O開銷,但session能夠實現某種程度的持久化,並且更有利於session的共享;數據結構
下面以Node.js中express框架的express-session插件來具體實現登陸狀態的保存(使用的MongoDB數據庫)
//當用戶點擊登陸選項時,以post方式將表單數據傳送到服務器
router.post('/login',function(req,res) {
//獲取表單數據 var body = req.body;
//User是數據庫模型 在該數據庫中查找是否有對應數據 User.findOne({ email:body.email, password:md5(md5(body.password)) },function(err,data) {
//服務器錯誤 if(err) { return res.status(500).json({ err_code:500, message:'server is busy' }); }
//若是找不到對應數據 說明輸入錯誤 if(!data) { return res.status(200).json({ err_code:1, message:'email or nickname is wrong!' }) }
//若是找到數據 則將找到的數據存入session的user屬性中 // 注意 存放的應該是數據庫中該用戶的數據 req.session.user = data; res.status(200).json({ err_code:0, message:'ok!' }) }) })
想要實現登陸狀態的保持,則存入的數據必定得是該用戶庫中存放的數據,方便後面的操做。存入數據後,沒法用戶訪問該主機哪一個頁面,數據都會存在,隨時均可以調用,也就實現了登陸狀態的保持
當咱們想退出登陸時,則應該講解session數據清空,也就等於退出了登陸狀態
router.get('/logout',function(req,res) { req.session.user = null; res.redirect('/'); })