首頁 >web前端 >js教程 >Node.js程式設計中客戶端Session的使用詳解_node.js

Node.js程式設計中客戶端Session的使用詳解_node.js

WBOY
WBOY原創
2016-05-16 15:53:221148瀏覽

 靜態網站很容易擴充。你只需要全部緩存,不需要考慮從不同伺服器組合有狀態的內容給用戶。

可惜,大多數的Web應用程式使用有狀態內容提供個人化體驗。如果你的應用程式可以登錄,就需要記住用戶的Session。經典的處理方法是客戶端設定包含隨機唯一Session標識的Cookie,被識別的Session資料保存到服務端。


擴充有狀態服務

當擴充服務的時候,你一定有三種選擇:

  1.     不同服務端同步Session資料
  2.     不同服務端連接單點中心(取得Session)
  3.     確保使用者存取相同服務端

但都有缺陷:

  •     同步資料增加效能開銷
  •     單點中心降低系統擴充性
  •     如果使用者上次存取的服務端需要維護怎麼辦

然而,如果你換個角度思考,你會發現第四個選擇:將Session資料保存在客戶端


客戶端Session

在客戶端保存Session有一些優點:

  •     無所謂哪個服務端,Session資料都有效
  •     不需要維護服務端狀態
  •     不需要服務端同步
  •     任意增加新的服務端

但是客戶端Session有一個嚴重問題:你不能保證使用者不會竄改Session資料。


例如你在Cookie中儲存用戶的ID。用戶很容易修改它,從而訪問別人的帳戶。

這似乎否定了客戶端Session的可能,但有一種方法可以巧妙解決這問題:加密打包Session資料(還是存在Cookie中)。這樣就不需要擔心用戶修改Session數據,服務端會驗證數據的。

實際應用上,就是Cookie中保存一個加密的Server Key。 Server Key驗證後才有權利讀取和修改Session資料。這就是客戶端Session。


Node客戶端Session

Node.JS有一個函式庫可以實作客戶端Session:node-client-session.它可以取代Connect(一個Node中間件框架)內建的session和cookieParser中介軟體。

在Express框架應用程式中的使用:
 

const clientSessions = require("client-sessions"); 
app.use(clientSessions({ secret: '0GBlJZ9EKBt2Zbi2flRPvztczCewBxXK' // 设置一个随机长字符串! })

然後,為req.session物件新增屬性:
 

app.get('/login', function (req, res){ req.session.username = 'JohnDoe'; });

讀取屬性:
 

app.get('/', function (req, res){ res.send('Welcome ' + req.session.username); });

使用reset方法終止Session:
 

app.get('/logout', function (req, res) { req.session.reset(); });

即時註銷Persona Session

(註:Persona是Mozzilla推出的網路身分系統)

與伺服器端Session不同,客戶端Session的問題是服務端無法刪除Session。

伺服器端架構時,你可以刪除Session資料。任意的客戶端Cookie標識的Session很可能不存在。但客戶端架構時,Session資料不在服務端,無法保證Session資料在每個客戶端都被刪除。換句話說,我們無法同步使用者的客戶端狀態(已經登入)和服務端狀態(登出登入)。
 

為了彌補這個缺陷,客戶端Session中加入了過期時間。展開Session資料(被加密打包)前驗證過期時間。如果過期了,拋棄Session資料並改變使用者狀態(如登出登入)。

過期機制在許多應用中運作良好(尤其是短過期時間需求)。如在Persona中,當使用者發覺密碼收到威脅或已經損壞時,我們需要提供方法讓使用者立即登出Session資料。

這表示需要保留一點點狀態資訊在服務後端。我們處理即時登出的方法是新增一個Token在使用者資料表和Session資料中。


每次API呼叫時比對Session資料中的Token和資料庫中的Token。如果不相同,返回錯誤訊息並退出使用者。

這樣會附加多餘的資料庫操作去查詢Token。幸好,大多數的API呼叫都需要讀取使用者資料表,把Token一起帶上就好了。


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn