日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

node --- [express] cookie/session 机制与 中间件的使用(路由守卫)

發布時間:2023/12/10 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 node --- [express] cookie/session 机制与 中间件的使用(路由守卫) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

說明

  • 源代碼
  • 記憶、遺忘回顧
  • 使用 cookie/session 機制,讓 客戶端/服務器 的訪問變得有狀態

cookie 與 session

  • 由于 HTTP 協議的無狀態性,當一次連接斷開后. 服務器并不會記錄用戶是否登錄. 因此需要引入 cookie/session 機制

cookie

cookie: 瀏覽器在電腦硬盤中開辟的一塊空間,主要供服務器端存儲數據

  • cookie 中的數據是以域名的形式進行區分的.

  • cookie 中的數據是有過期時間的,超過時間數據會被瀏覽器自動刪除.

  • cookie 中的數據會隨著請求被自動發送到服務器

    1.客戶端第一次向服務器端發送請求的時候,是不存在 cookie 的.
    2.服務端驗證客戶端,會響應一個 cookie 給客戶端.
    3.客戶端驗證通過后,在發送請求會自動帶上 cookie


session

session:實際上就是一個對象,存儲在服務器端的內存中,在 session 對象中也可以存儲多條數據,每一條數據都有一個 sessionid 做為唯一標識.

注意:cookie 在客戶端的磁盤中,session 在服務端的內存中


cookie 和 session 的使用(理論)

  • [client] --> 郵件地址、密碼 --> [server]
  • server 端,對郵箱地址、密碼進行驗證,若通過則生成 sessionid
  • [client] <-- sessionid(存儲在客戶端的 cookie 中) <-- [server]
  • 客戶端再次登錄
  • [client] --> cookie [server]
  • 服務端,獲取 cookie 中的 sessionid,驗明身份后,響應數據
  • 實戰: cookie 與 session

    • 配置獲取POST請求參數
    // 配置獲取post參數 const bodyParser = require('body-parser') // extended: false 方法內部使用querystring模塊處理請求參數的格式 // extended: true 方法內部使用第三方模塊qs處理請求參數的格式 // 攔截所有請求 app.use(bodyParser.urlencoded({ extended: false }))
    • 驗證成功后,生產session信息
    const User = require('../../model/user') const session = requier('express-session') app.use(session({ secret: 'secret key' })) admin.post('/login', async (req, res) => {const { email, password } = req.bodyconst user = await User.findOne({ email })// 假設登錄成功req.session.username = user.username // 此處能用req.session是在app.js中使用app.use方法進行了攔截 })
    • User是使用mongoose的接口創建的集合規則
    • User.findOne(): 通過郵箱再數據庫中查找數據
    • req.session.username: 執行后,會在內存中創建

    中間件的使用

    什么是中間件

    • 中間件就是一堆方法
    • 可以接收客戶端發來的請求、可以對請求做出響應,也可以將請求繼續交給下一個中間件繼續處理.
    • 將一個復雜的請求處理邏輯分開處理
    • 也可以將請求到達指定路由前,先進行驗證處理: 如用戶是否登錄

    中間件的構成

    • 中間件方法以及請求處理函數
    • 中間件方法: 由Express提供,負責攔截請求,請求處理函數由開發人員提供,負責處理請求.
    app.get('請求路徑', '處理函數'); // 接收并處理get請求 app.post('請求路徑', '處理函數'); // 接收并處理post請求
    • 可以對同一請求設置多個中間件,對同一請求進行多次處理
    • 默認情況下,請求從上到下依次匹配中間件,一旦匹配成功,終止匹配
    • 可以調用next方法將請求的控制權交給下一個中間件,直到遇到結束請求的中間件.
    app.get('/request', (req, res, next) =>{req.name = "張三";next(); }) app.get('/request', (req,res) =>{res.send(req.name); });

    app.use的使用

    • 它有2個參數, 第一個參數不寫對所有路徑的請求進行攔截
    • 若填寫了第一個參數,則對該路徑下的路由進行攔截
    • 第二個參數是路由處理函數
    // 攔截所有路由 app.use((req,res,next)=>{console.log(req.url);next(); })// 攔截 /admin 下的所有路由 app.use('/admin', (req, res, next)=>{console.log(req.url);next() })

    路由守衛

    • 簡單的說就是在所有路由前面或者后面,針對特定路徑或所有路徑的一個特殊的app.use方法.

    登錄守衛

    • 放在所有的路由前面,即客戶端訪問第一個經過的函數
    // 攔截 -> 路由守衛 app.use('/admin', require('./middleware/loginGuard'))// 其他路由中間件 app.get(...); app.post(...);
    • loginGuard
    module.exports = (req, res, next) => {if (req.url !== '/login') {// 訪問的不是登錄頁面// 判斷用戶是否登錄if (req.session.username) {next()} else {res.redirect('/admin/login')}} else {// 訪問的是登錄頁面next()} }
    • next: 將執行權,傳遞給下一個中間件
    • res.redirect: 重定向到路由 /admin/login

    錯誤守衛

    • 放在比較靠后的中間件. 用來收集錯誤信息
    // 其他路由中間件 app.get(...); app.post(...);// 錯誤 -> 路由守衛 app.use(require('./middleware/errorGuard.js'))
    • 當其他路由發現錯誤時(如驗證不通過),使用next將執行權往后傳遞.
    • 傳遞到最后,有錯誤守衛對錯誤信息進行收集.
    • 發現錯誤并傳遞錯誤的代碼(部分)如下:
    // 比如在更新用戶信息的時候,新傳遞的數據和數據庫里面的格式不符合 try {await validateUser(req.body) } catch (ex) {return next(JSON.stringify({ path: '/admin/user-edit', msg: ex.message })) }

    validateUser: 是驗證用戶信息的一個函數,驗證通過返回true,否則會拋出異常.
    catch: 用于捕獲異常.
    return: 是阻止程序向下執行.
    JSON.stringfify: 是因為app.use(param1,param2)中的param2的第一個參數err只接收一個字符串類型.因此需要使用該方法將對象轉換成字符串

    • 此時函數的執行權,交給了下一個中間件errorGuard.js
    module.exports = (err, req, res, next) => {const result = JSON.parse(err)let params = []for (let attr in result) {if (attr != 'path') {params.push(attr + '=' + result[attr])}}res.redirect(`${result.path}?${params.join('&')}`) }
    • 它將收集到的參數拼接成get請求的參數部分. 然后重定向

    總結

    以上是生活随笔為你收集整理的node --- [express] cookie/session 机制与 中间件的使用(路由守卫)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。