- 什么是session
- Express session實例應用
- Express session源碼解析
一、什么是session
二、Express session實例應用(登入驗證)
npm init -y npm install express -save-dev npm install cookie-parser -save-dev npm install express-session -save-dev npm install body-parser -save-dev npm install ejs -save-dev //項目結構 express_session page login.html home.html index.js node_modules package.json package-lock.json
這個實例主要解析node后台的express-session的應用,就不采用前端的數據渲染框架,而是采用后端模板渲染框架ejs。ejs官方文檔:https://ejs.bootcss.com/
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登入頁面</title> 6 </head> 7 <body> 8 <form action="/login" method="POST"> 9 賬號:<input type="text" name="userid" /> 10 密碼:<input type="password" name="userpassword"/> 11 <input type="submit" value="登入"> 12 </form> 13 </body> 14 </html>
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>首頁</title> 6 </head> 7 <body> 8 <p id="use">用戶:<%= username %> | 賬號:<%= userid %></p> 9 <p><a href="/logout">退出</a></p> 10 </body> 11 </html>
1 //后台核心代碼 2 const express = require('express'); 3 const cookieParser = require('cookie-parser'); 4 const session = require('express-session'); 5 const bodyParser = require('body-parser'); 6 const app = express(); 7 8 app.use(cookieParser()); 9 app.use(session({ 10 cookie:{maxAge:1000*30}, 11 secret:'leo' 12 })); 13 14 app.set("view engine","html");//設置解析魔棒的文件類型 15 app.set("views", __dirname+ "\\page");//設置模板路徑 16 app.engine('html',require('ejs').renderFile);//指定ejs引擎解析渲染模板路徑下的html文件 17 18 app.use(bodyParser.json()); 19 app.use(bodyParser.urlencoded({extended: true})); 20 21 22 //獲取登入頁面 23 app.get('/login',function(req,res){ 24 res.sendFile(__dirname + '/page/login.html'); 25 }); 26 27 //用戶登入(登入賬號驗證) 28 app.post('/login',function(req,res){ 29 if(req.body.userid === '12300001111' && req.body.userpassword === '123456'){ 30 req.session.userid = req.body.userid; //登入成功,設置session 31 req.session.username = '他鄉踏雪'; //... 32 res.redirect('/home'); 33 }else{ 34 res.json({ret_code:1,ret_msg:'賬號密碼錯誤'}); 35 } 36 }); 37 38 //獲取主頁(響應首頁前通過session驗證用戶是否登入) 39 app.get('/home',function(req,res){ 40 if(req.session.userid){ 41 res.render('home',{ 42 username:req.session.username, 43 userid:req.session.userid 44 }); 45 }else{ 46 res.redirect('/login'); 47 } 48 }); 49 50 //退出 51 app.get('/logout',function(req,res){ 52 req.session.username = null; 53 req.session.userid = null; 54 res.redirect('/login'); 55 }); 56 57 app.listen(12306);
三、Express session原理及源碼解析
3.1基於cookie的session:

從某種意義上來說,session就是服務端的cookie,而且session是基於cookie的,就會受到瀏覽器的用戶禁用cookie的限制,在IE8時期可以通過HTML5的storage來填補這一空缺,因為在即便是瀏覽器禁用了cookie也僅僅只是不能在本地存儲cookie,服務的session如果根據IP和一系列數據簽名匹配到相關session,然后響應頭還是會攜帶cookie,所以就可以通過js解析cookie然后在本地使用storage來替代cookie,這是本地禁用cookie的解決方案。
同樣在服務端由於session默認存儲再內存中,如果服務停止或重啟內存的數據就會被清除,所以再服務端也是有必要對session做持久化的,這些在session上針對不同的session都由豐富的插件模塊,下面這份代碼是在第一部分基礎上實現了session文本存儲持久化,使用的是:session-file-store(官方文檔:https://www.npmjs.com/package/session-file-store),詳細見代碼。
1 const express = require('express'); 2 const cookieParser = require('cookie-parser'); 3 const session = require('express-session'); 4 const bodyParser = require('body-parser'); 5 //session-file-store官方文檔:https://www.npmjs.com/package/session-file-store 6 //express-session官方文檔(更多session存儲模式可以參考這個):https://github.com/expressjs/session 7 const FileStore = require('session-file-store')(session);//引入session本地文件存儲模塊 8 const fileStoreOptions = {};//配置session本地存儲模塊的相關參數,空對象表示默認參數,詳細參考 9 const app = express(); 10 11 12 13 app.use(cookieParser()); 14 app.use(session({ 15 store: new FileStore(fileStoreOptions),//啟動session本地文件存儲 16 cookie:{maxAge:1000*30}, 17 secret:'leo' 18 })); 19 20 app.set("view engine","html");//設置解析魔棒的文件類型 21 app.set("views", __dirname+ "\\page");//設置模板路徑 22 app.engine('html',require('ejs').renderFile);//指定ejs引擎解析渲染模板路徑下的html文件 23 24 app.use(bodyParser.json()); 25 app.use(bodyParser.urlencoded({extended: true})); 26 27 28 //獲取登入頁面 29 app.get('/login',function(req,res){ 30 res.sendFile(__dirname + '/page/login.html'); 31 }); 32 33 //用戶登入(登入賬號驗證) 34 app.post('/login',function(req,res){ 35 if(req.body.userid === '12300001111' && req.body.userpassword === '123456'){ 36 req.session.userid = req.body.userid; //登入成功,設置session 37 req.session.username = '他鄉踏雪'; //... 38 res.redirect('/home'); 39 }else{ 40 res.json({ret_code:1,ret_msg:'賬號密碼錯誤'}); 41 } 42 }); 43 44 //獲取主頁(響應首頁前通過session驗證用戶是否登入) 45 app.get('/home',function(req,res){ 46 if(req.session.userid){ 47 res.render('home',{ 48 username:req.session.username, 49 userid:req.session.userid 50 }); 51 }else{ 52 res.redirect('/login'); 53 } 54 }); 55 56 //退出 57 app.get('/logout',function(req,res){ 58 req.session.username = null; 59 req.session.userid = null; 60 res.redirect('/login'); 61 }); 62 63 app.listen(12306);
更多session持久化可以參考session的官方文檔:https://github.com/expressjs/session,比較常見的MongoDB、Redis。
2.session源碼淺析:
這一部分主要參考這篇博客:https://blog.csdn.net/weixin_33824363/article/details/91393870
session源碼只有四個模塊,分別是:cookie.js、memory.js、session.js、store.js再加一個入口模塊index.js。
cookie:用來配置cookie相關的參數。
store:用來實現session數據持久化操作的模塊。
session:主程序模塊。
memory:用來實現數據緩存,也就是session默認情況下存儲在內存中的操作。
index:入口模塊。
