世界上任何一個(gè)擁有用戶(hù)數(shù)據(jù)的 web 應(yīng)用都必須處理 sessions。作為一名開(kāi)發(fā)者,我們必須要知道它們是什么以及如何處理它們。
在這篇文章中,我想要分享的是:
session 是什么?
session 如何存儲(chǔ)數(shù)據(jù)?
你如何決定存放 session 數(shù)據(jù)的位置?
在 sessions 工作時(shí),你必須意識(shí)到的安全性上的影響有哪些?
在一些示例代碼中,我將會(huì)運(yùn)用?session npm module ,它很有可能是最常見(jiàn)的 session 庫(kù)。
session 是存儲(chǔ)你通過(guò)請(qǐng)求獲取到的數(shù)據(jù)的地方。每一個(gè)訪(fǎng)問(wèn)你網(wǎng)站的用戶(hù)都有一個(gè)唯一的 session。當(dāng)他們?yōu)g覽你應(yīng)用的時(shí)候,你就可以使用 session 去存儲(chǔ)和獲取用戶(hù)數(shù)據(jù)。
session 對(duì) web 應(yīng)用開(kāi)發(fā)來(lái)講是必須有的,因?yàn)?session 允許應(yīng)用去存儲(chǔ)狀態(tài)?;谟脩?hù)在頁(yè)面 A 上的一個(gè)動(dòng)作,我們就可以展示出一個(gè)不同的頁(yè)面 B。如果沒(méi)有 session,應(yīng)用將是無(wú)狀態(tài)的,而且很無(wú)用。
這里展示了你如何使用 Express 去建立一個(gè)簡(jiǎn)單的 session
import express from "express"; import session from "express-session"; var app = express(); app.use(session());
如果你的應(yīng)用已經(jīng)有了可使用的 sessions, 你可以在一個(gè)路由處理中設(shè)置一些數(shù)據(jù):
app.use(session({ secret: "this-is-a-secret-token", cookie: { maxAge: 60000 }})); // Access the session as req.session app.get("/", function(req, res, next) { var sessData = req.session; sessData.someAttribute = "foo"; res.send("Returning with some text"); });
在另一個(gè)路由處理中讀到它:
app.get("/bar", function(req, res, next) { var someAttribute = req.session.someAttribute; res.send(`This will print the attribute I set earlier: ${someAttribute}`); });
sessions 可以用不同的方式存儲(chǔ)它們的信息。存儲(chǔ) session 數(shù)據(jù)最受歡迎的方式有:
在應(yīng)用內(nèi)存中
在 cookie 中
在內(nèi)存緩存中
在數(shù)據(jù)庫(kù)中
使用應(yīng)用內(nèi)存存儲(chǔ) session 數(shù)據(jù)這是常見(jiàn)的最簡(jiǎn)單的存儲(chǔ)方式,但在生產(chǎn)環(huán)境中不用。
用這種方式存儲(chǔ)從根本上意味著數(shù)據(jù)在應(yīng)用執(zhí)行時(shí)間中的有效期內(nèi)被存儲(chǔ),一旦你的 web 應(yīng)用服務(wù)器宕機(jī)了或停止運(yùn)行了,所有的 session 數(shù)據(jù)都會(huì)被移除。
在內(nèi)存中存儲(chǔ) session 數(shù)據(jù)也會(huì)導(dǎo)致內(nèi)存泄露。當(dāng)你的應(yīng)用保持運(yùn)行的時(shí)候,越來(lái)越多的內(nèi)存被占用,直到應(yīng)用因?yàn)閮?nèi)存不足而退出。
為了開(kāi)發(fā)的目的,把 session 數(shù)據(jù)存在內(nèi)存中經(jīng)常很有用。然而,這兒還有更好的存儲(chǔ) session 數(shù)據(jù)的方式。
cookie 通常是從 web 服務(wù)器發(fā)送到你的 web 瀏覽器上的一小塊數(shù)據(jù)。它允許服務(wù)器存儲(chǔ)一個(gè)具體用戶(hù)相關(guān)的信息。
cookies 的一種常見(jiàn)用法就是存儲(chǔ) session 數(shù)據(jù),它的工作流程是:
1、服務(wù)器發(fā)送一個(gè) cookie 給 web 瀏覽器,并且在客戶(hù)端存儲(chǔ)一段時(shí)間(稱(chēng)為 expiration time)。
2、當(dāng)用戶(hù)隨后向 web 服務(wù)器發(fā)起一個(gè)請(qǐng)求時(shí),這個(gè) cookie 會(huì)和這個(gè)請(qǐng)求一起發(fā)送,服務(wù)器可以讀到 cookie 中包含的信息。
3、如果需要的話(huà),服務(wù)器可以修改 cookie,然后再把它返回給瀏覽器。
每次你發(fā)起一個(gè)請(qǐng)求,你的瀏覽器都會(huì)把 cookie 發(fā)送給服務(wù)器,直到 cookie 過(guò)期為止。
類(lèi)似 express-session 這樣的模塊會(huì)給你提供一個(gè)友好的 API 和 sessions 一起工作(讓你可以獲取 & 設(shè)置 session 里的數(shù)據(jù) ),但是在底層,它可以通過(guò) cookie 保存和恢復(fù)這個(gè)數(shù)據(jù)。
Express-session?也提供一些方法來(lái)保證你 cookies 的安全性。我們?cè)谶@不會(huì)講述安全細(xì)節(jié),但是我推薦你通過(guò)閱讀文檔來(lái)詳細(xì)研究安全細(xì)則。這對(duì)于確保你應(yīng)用里的 cookie 信息不被暴露是非常重要的。
使用 cookie 存儲(chǔ) session 數(shù)據(jù)也帶來(lái)了一些問(wèn)題:
1、可以存儲(chǔ)的數(shù)據(jù)量很小,大約只有 4kb。
2、因?yàn)槊看伟l(fā)送請(qǐng)求都會(huì)攜帶 cookie,如果你在 cookie 中存儲(chǔ)了一堆數(shù)據(jù),它將會(huì)增加請(qǐng)求中的數(shù)據(jù)量,從而導(dǎo)致你的網(wǎng)站性能降低。
3、如果攻擊者弄清楚了你的 cookies 是如何加密的,那么你的 cookies 就危險(xiǎn)了。攻擊者將能讀到 cookies 中存儲(chǔ)的信息,這可是用戶(hù)敏感信息?。?/p>
使用內(nèi)存緩存存儲(chǔ) session 數(shù)據(jù)
內(nèi)存緩存是可以存儲(chǔ)一小堆鍵值數(shù)據(jù)的地方。使用內(nèi)存緩存存儲(chǔ) session 信息的最出名的兩個(gè)例子就是 ?Redis 和 ?Memcached。
在內(nèi)存緩存中存儲(chǔ) session 數(shù)據(jù)的時(shí)候,服務(wù)器仍然使用 cookie,但是這個(gè) cookie 只包含一個(gè)唯一的 sessionId。這個(gè) sessionId 在服務(wù)器對(duì)儲(chǔ)存庫(kù)進(jìn)行查找的時(shí)候使用。
使用內(nèi)存緩存的時(shí)候,你的 cookie 只包含一個(gè) session ID。它避免了私人用戶(hù)信息被暴露在 cookie 中的危險(xiǎn)。
使用內(nèi)存緩存存儲(chǔ) session 數(shù)據(jù)的優(yōu)點(diǎn):
1、基于鍵值對(duì)數(shù)據(jù)存儲(chǔ),便于查找。
2、它們和你的應(yīng)用服務(wù)器分隔開(kāi)來(lái)。這種分隔降低了依賴(lài)。
3、多帶帶一個(gè)內(nèi)存存儲(chǔ)可以服務(wù)好多個(gè)應(yīng)用。
4、通過(guò)移除老的 session 數(shù)據(jù)來(lái)自動(dòng)管理內(nèi)存。
當(dāng)然,這種存儲(chǔ)方式也有一些缺點(diǎn):
1、它們是另一臺(tái)服務(wù)器,需要進(jìn)行建立和管理。
2、對(duì)一些小應(yīng)用來(lái)說(shuō)可能是殺雞用了牛刀。一般這種情況的話(huà),使用數(shù)據(jù)庫(kù)存儲(chǔ)或者 cookies 存儲(chǔ)效果更好。
3、重置緩存的唯一辦法就是移除所有存儲(chǔ)在它里面的 sessions。
下面的示例告訴你如何來(lái)用 express-session 來(lái)建立一個(gè)類(lèi)似 Memcached 的內(nèi)存緩存,通過(guò) ?connect-memcached 模塊。
var express = require("express"); var session = require("express-session"); var cookieParser = require("cookie-parser"); var app = express(); var MemcachedStore = require("connect-memcached")(session); app.use(cookieParser()); app.use(session({ secret : "some-private-key", key : "test", proxy : "true", store : new MemcachedStore({ hosts: ["127.0.0.1:11211"], //this should be where your Memcached server is running secret: "memcached-secret-key" // Optionally use transparent encryption for memcache session data }) }));使用數(shù)據(jù)庫(kù)存儲(chǔ) session 數(shù)據(jù)
最后,我們談一下在傳統(tǒng)的數(shù)據(jù)庫(kù)中存儲(chǔ) session 數(shù)據(jù),比如 MySQL 和 PostgreSQL。在大多數(shù)情況下,它以一種類(lèi)似于在內(nèi)存中存儲(chǔ) session 數(shù)據(jù)的方式來(lái)工作。
session cookie 仍然只含有一個(gè) sessionId。在這種情況下,它將會(huì)匹配數(shù)據(jù)庫(kù)里的 session 表中的第一個(gè) key 值。
總的來(lái)講,我不推薦使用數(shù)據(jù)庫(kù)來(lái)存儲(chǔ) session 數(shù)據(jù),我這么做的唯一的理由是它需要花費(fèi)大量精力去建立 ?Memcached? 或 Redis。
從數(shù)據(jù)庫(kù)中恢復(fù)數(shù)據(jù)比用內(nèi)存緩存恢復(fù)要慢的多,因?yàn)閿?shù)據(jù)存儲(chǔ)在硬盤(pán)上,而不是內(nèi)存中。當(dāng)你把 session 數(shù)據(jù)存在數(shù)據(jù)庫(kù)里的時(shí)候,你會(huì)被數(shù)據(jù)庫(kù)暴擊的。。。。
另外,你必須自己全權(quán)管理老的 session 數(shù)據(jù)。如果你沒(méi)有移除老的 session 數(shù)據(jù),你的數(shù)據(jù)庫(kù)將被成千上萬(wàn)條無(wú)用數(shù)據(jù)行占用。
這里有許多數(shù)據(jù)庫(kù)存儲(chǔ),你可以使用 express-session。在 ?README 中查看完整列表。
我們討論了常用的三種方式存儲(chǔ)來(lái)存儲(chǔ)你的 session 數(shù)據(jù)。那么你應(yīng)該在哪存儲(chǔ)你的 session 數(shù)據(jù)呢?
總的來(lái)說(shuō),我遵循這個(gè)規(guī)則:“內(nèi)存第一(譯者注:這里應(yīng)該是指內(nèi)存緩存),cookie 第二,最后是數(shù)據(jù)庫(kù)”。
如果你使用 Memcached 或 Redis,我會(huì)和你相伴。如果不是,把你的 session 數(shù)據(jù)存在 cookie,但一定要確保你私鑰的安全。最后,你可以把你的 session 數(shù)據(jù)存在數(shù)據(jù)庫(kù)里,但一定要有一個(gè)移除老 session 數(shù)據(jù)的計(jì)劃。
原文地址:http://nodewebapps.com/2017/0...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/61881.html
摘要:首先安裝單元測(cè)試環(huán)境使用模塊來(lái)模擬定義的模型。根據(jù)刪除這是單元測(cè)試的最后一小節(jié)。需要根據(jù)需求和單元測(cè)試用例來(lái)編寫(xiě)應(yīng)用邏輯,使我們的程序更加穩(wěn)定。我們會(huì)運(yùn)行自動(dòng)測(cè)試用例,一直重構(gòu),直到所有單元測(cè)試都通過(guò)。 本文轉(zhuǎn)載自:眾成翻譯譯者:文藺鏈接:http://www.zcfy.cc/article/746原文:https://semaphoreci.com/community/tutoria...
摘要:首先安裝單元測(cè)試環(huán)境使用模塊來(lái)模擬定義的模型。根據(jù)刪除這是單元測(cè)試的最后一小節(jié)。需要根據(jù)需求和單元測(cè)試用例來(lái)編寫(xiě)應(yīng)用邏輯,使我們的程序更加穩(wěn)定。我們會(huì)運(yùn)行自動(dòng)測(cè)試用例,一直重構(gòu),直到所有單元測(cè)試都通過(guò)。 本文轉(zhuǎn)載自:眾成翻譯譯者:文藺鏈接:http://www.zcfy.cc/article/746原文:https://semaphoreci.com/community/tutoria...
摘要:感謝使用框架本文檔涵蓋構(gòu)建應(yīng)用所需的基礎(chǔ)知識(shí)。用于數(shù)據(jù)校驗(yàn)的組件及相關(guān)文件在此目錄進(jìn)行管理。除了自定義中間件外,還是用了諸多第三方的中間件,它們是五測(cè)試我們使用組件對(duì)服務(wù)端代碼進(jìn)行測(cè)試。識(shí)別當(dāng)前導(dǎo)航從已有導(dǎo)航中刪除給定標(biāo)識(shí)的導(dǎo)航配置。 本文同步至個(gè)人博客 MEAN.js 文檔,轉(zhuǎn)載請(qǐng)注明出處。 Overview 感謝使用 MEAN.js 框架! 本文檔涵蓋構(gòu)建 MEAN 應(yīng)用所需的基礎(chǔ)...
摘要:事件處理器,則是當(dāng)指定事件觸發(fā)時(shí),執(zhí)行的一段代碼。事件循環(huán)以一個(gè)無(wú)限循環(huán)的形式啟動(dòng),存在于二進(jìn)制文件里函數(shù)的最后,當(dāng)沒(méi)有更多可被執(zhí)行的事件處理器時(shí),它就退出。 前言 如果你了解過(guò)Node.js,那么你一定聽(tīng)說(shuō)過(guò)事件循環(huán)。你一定想知道它為什么那么特殊,并且為什么你需要關(guān)注它?此時(shí)此刻的你,可能已經(jīng)寫(xiě)過(guò)許多基于Express.js的后端代碼,但沒(méi)有接觸到任何的循環(huán)。 在下文中,我們會(huì)先在一...
閱讀 3021·2023-04-26 00:23
閱讀 3427·2021-09-13 10:28
閱讀 2218·2021-08-31 14:18
閱讀 2919·2019-08-30 15:54
閱讀 1973·2019-08-30 15:43
閱讀 1322·2019-08-29 16:56
閱讀 2833·2019-08-29 14:16
閱讀 2081·2019-08-28 17:51