HTTP協議的無狀態性
1)HTTP協議的通信模型: 基於 請求--處理 ---響應
2)由於這個通信協議的關系,導致了HTTP每次請求之間都是沒有關聯的。每當一個請求完成之后,服務器就忘記之前誰曾經請求過!
3)我們純粹基於HTTP通信模型,是無法完成登錄狀態保持的!每次請求服務器,服務器都會把這個請求當作新請求來處理!
4)我們可以通過cookie技術,實現狀態保持,但是由於cookie是存儲在客戶端的一門技術,所以安全性幾乎沒有。因此,不要使用cookie存儲敏感
的數據。
cookie介紹
什么是cookie,作用是什么?
1)由於HTTP協議是無狀態的,且傳統的服務器只能被動的響應請求。所以服務器獲取到請求的時候,並不知道當前請求是哪個客戶端的!
2) 服務器為了能夠區分每個客戶端,需要使用一些小技術,來根據不同的請求區分不同的客戶端。
3)只要有請求發生,那么必然對應一個客戶端。在每次客戶端發起請求的時候,向服務器自動發送一個標識符,告訴服務器當前是哪個客戶端正在請求服務器的數據。
4)如何提供這個標識符號?可以在請求頭中添加一個標簽,叫做cookie。每次發送請求,都會把這個cookie隨同其他報文一起發送給服務器,服務器可以根據報文中的cookie 區分不同的客戶端瀏覽器。
5)如何在客戶端請求中添加標識符?
在NODE中可以writeHeader的時候,通過set-cookie來將cookie標識符通過響應報文發送給客戶端。
6)客戶端也可以通過一些方式來操作自己的cookie,比如: jquery.cookie
cookie的基本使用
var http = require('http');
var server = http.createServer();
server.on('request',function(req,res)=>{
//解析cookie
var cookies ={}
var cookieStr = req.headers.cookie;
cookieStr && cookieStr.split(';').forEach(function(item){
var params = item.split('=');
cookies[params[0].trim()] = params[1].trim();
})
res.writeHeader(200,{
'Content-Type':'text/plain; charset=utf8',
'Set-Cookie':['issend=ok','age=20']
});
if(cookie.issend ==='ok'){
res.end('NO')
}else{
res.end('yes')
}
})
server.listen(4000,function(){
console.log('run')
})
通過expires 設置 cookie的過期時間
var expiresTime = new Date(Date.now()+1000*60).toUTCString();
res.writeHeader(200,{
'Content-Type':'text/html; charset=utf-8',
'Set-Cookie':['isvisit=true; expires='+expiresTime]
})
cookie可以被偽造,不安全;
使用谷歌插件 edit this cookie,就能偽造cookie數據!所以不要使用cookie存儲敏感的數據!比如登錄狀態和登錄信息,這些應該存儲在服務器端。
什么是Cookie的應用場景:
1)對安全性要求不高
2)不需要存儲大量的數據
3) 主用應用場景,是用來做客戶端與服務器之間的狀態保持技術。
Session登錄退出及狀態保存
使用express-session來保存登錄狀態
1)什么是session?
由於HTTP是無狀態的,所以服務器在每次連接中持續保存客戶端的私有數據此時需要結合cookie技術。通過session 會話機制,在服務器端保存每個http請求的私有數據。
2)session原理
在服務器內存中開辟一塊地址空間,專門存放每個客戶端的私有數據,每個客戶端根據cookie中保持的sessionId,可以獲取到session數據。
3)在express中使用session
a)安裝session模塊
npm install express-session -S
b) 導入session模塊
var session = require('express-session');
c)在express中使用session中間件
app.use(session({
secret:'keyboard cat',//相當於一個加密密鑰,值可以是任意字符串
resave:false,//強制session保存到session store中
saveUninitialiazed:false //強制沒有‘初始化’的session保存到storage中
}))
d)將私有數據保存到當前請求的session會話中
req.session.user = result.dataValues
req.session.islogin = true;
e)通過destroy()方法情況session數據
req.session.destory(function(err){
if(err) throw err;
res.redirect('/');
})