亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Web Session 淺入淺出

李昌杰 / 1330人閱讀

摘要:通過瀏覽器的,可以看到此次會話的請求內(nèi)容和響應(yīng)內(nèi)容。是協(xié)議的一部分。真實(shí)的產(chǎn)品,一般是創(chuàng)建一個(gè)保證唯一的,不易猜測出來的字符串。因此需要數(shù)據(jù)持久化的多提供者的方案。

使用過幾種Web App開發(fā)語言和框架,都會接觸到Session的概念。即使是一個(gè)簡單站點(diǎn)訪問計(jì)數(shù)的功能,也常常使用Session來實(shí)現(xiàn)的。其他常用的領(lǐng)域還有購物車,登錄用戶等。但是,對Session一直是一知半解,知其然而不知其所以然。

在認(rèn)真的研究了HTTP協(xié)議,以及nodejs開發(fā)棧的express和express-session后,我終于比較有把握深入淺出的說清楚Session了,也算是滿足了多年來開發(fā)過程中,常常浮現(xiàn)的對Session的好奇心吧。

本文使用nodejs v9.5.0作為技術(shù)驗(yàn)證工具。閱讀本文前需要了解基礎(chǔ)的HTTP知識和Cookie知識。詳細(xì)需要參考rfc6265,或者閱讀《HTTP小書》的最后一章。

會話的概念

用戶在網(wǎng)站的一組相互關(guān)聯(lián)的的請求和響應(yīng),就是一次會話。簡而言之是這樣的:

會話 = 一組訪問

訪問 = 一次請求和響應(yīng)

比如一個(gè)最簡單的nodejs HTTP程序:

var http = require("http")
http.createServer(function(req,res){
    res.end("hello")    
}).listen(3000)

每個(gè)請求都會進(jìn)入到此處理函數(shù):function(req,res){res.end("hello") },在此函數(shù)內(nèi)獲得請求,處理響應(yīng),完成后發(fā)給客戶端,就是一次訪問。通過瀏覽器的developer tools,可以看到此次會話的請求內(nèi)容和響應(yīng)內(nèi)容。

以站點(diǎn)計(jì)數(shù)應(yīng)用為案例來說明的話,就是這些來自于同樣訪問者的多次訪問,都可以獲得當(dāng)前站點(diǎn)的訪問計(jì)數(shù)。

引入會話

我們從一個(gè)案例開始引入會話的概念。當(dāng)我們需要訪問站點(diǎn)計(jì)數(shù)一類的功能時(shí),我們希望用戶訪問此站點(diǎn)時(shí):

第一次訪問時(shí),顯示你的訪問次數(shù)為1

以后每次訪問時(shí),訪問計(jì)數(shù)加1

此種情況下,我們需要有一個(gè)地方存儲當(dāng)前計(jì)數(shù),這樣才能在同一個(gè)客戶在此訪問時(shí),可以取出當(dāng)前計(jì)數(shù),加一后返回給客戶。當(dāng)然也因此需要識別此用戶(瀏覽器),為每個(gè)用戶多帶帶計(jì)數(shù)。就是說,不同的用戶訪問時(shí),需要去取對應(yīng)用戶的當(dāng)前計(jì)數(shù)。

識別客戶的問題,常用的方法就是使用Cookie。Cookie是HTTP協(xié)議的一部分。HTTP可以通過頭字段Set-Cookie為來訪客戶做一個(gè)標(biāo)記,這個(gè)標(biāo)記常常就是一個(gè)ID,下一次訪問此站點(diǎn)時(shí),HTTP會通過Cookie頭字段,發(fā)送此ID到站點(diǎn),由此站點(diǎn)知道此客戶的身份和這個(gè)身份關(guān)聯(lián)的狀態(tài)信息,比如當(dāng)前訪問計(jì)數(shù),或者此身份當(dāng)前的購物車的內(nèi)容等等。

識別了客戶后,就可以在Web服務(wù)器內(nèi),為此客戶建立它的獨(dú)特的狀態(tài)信息。

實(shí)現(xiàn)一個(gè)會話

基于nodejs HTTP模塊,我們實(shí)現(xiàn)一個(gè)極為簡單的Session服務(wù)。只是為了展示概念,而不是為了實(shí)用的目的。此服務(wù)可以實(shí)現(xiàn)一個(gè)共享于同一站點(diǎn)的多次訪問的req.session變量,此變量為一個(gè)對象,可以在此變量內(nèi)寫入新的成員,或者修改現(xiàn)存的成員變量的值,每次訪問后會保存req.session,以便下次訪問可以得到當(dāng)前的值:

var http = require("http")
var sessionkey = "sessionkey3"
http.createServer(function(req,res){
    if (req.url =="/"){
        session(req,res)
        req.session.count = (req.session.count+1) || 1
        res.end("hi"+req.session.count)
    }else
        res.end("")    
}).listen(3000)
console.log("listen on 3000")
function session(req,res){
    if (req.session)
        return
    var answer ,id
    if(isSessionOk(req)){
        id = getCookie(req)
        answer = getSessionById(id)
    }else{
        answer=  {}
        id = createSession(answer)
        setCookie(res,id)
    }
    req.session = answer
    res.on("finish", function() {
        saveSession(id,req.session)
    });
}
function hasCookie(req){
  return (getCookie(req)!="") 
}
function getCookie(req){
  try{
      var c = req.headers["cookie"]
      var arr = c.split(";")
      for (var i = 0; i < arr.length; i++) {
          var kv = arr[i]
          var a = kv.split("=")
          if (a[0].trim() == sessionkey)
              return a[1]
      }
  }catch(error){
      return ""
  }
  return ""
}
function setCookie(res,id){
  res.setHeader("set-cookie",sessionkey +"="+id)
}
var sessions = {}
var sid = 0  
function getSessionById(sid){
    return sessions[sid]
}
function getSessionByReq(req){
    var sid = getCookie(req)
    return sessions[sid]
}
function createSession(session){
    sessions[sid++,session]
    return sid
}
function saveSession(sid,session){
    sessions[sid] = session
}
function isSessionOk(req){
    return hasCookie(req) && getSessionByReq(req) !== undefined
}

程序代碼比較簡單,讀者可以保持它到index.js,然后執(zhí)行此程序,驗(yàn)證概念:

node index.js 

然后,啟動chrome,訪問站點(diǎn)localhost:3000,然后多次刷新,你可以看到每次刷新,返回的訪問次數(shù)逐步累加。在打開另一個(gè)瀏覽器,比如safari,在此訪問此站點(diǎn),你會發(fā)現(xiàn)返回的訪問計(jì)數(shù)從1開始,另外計(jì)數(shù)。因?yàn)槭莾蓚€(gè)不同的瀏覽器內(nèi)器,這就保證的它們是不同的訪問客戶,在站點(diǎn)內(nèi)的代碼,會區(qū)別兩者,分別記錄它們的狀態(tài)信息。

代碼使用了HTTP Cookie,基本算法很簡單:

如果Session沒有準(zhǔn)備好,那么創(chuàng)建一個(gè)Session,得到Session的ID,把此ID通過Set-Cookie發(fā)送給瀏覽器。瀏覽器會在下一次訪問此站點(diǎn)時(shí),發(fā)送此ID。

如果Session已經(jīng)準(zhǔn)備好了,也就是說,瀏覽器通過Cookie發(fā)來了ID,并且通過此ID,可以在站點(diǎn)內(nèi)獲取到Session

把創(chuàng)建或者獲取的Session賦值給req對象

在請求處理函數(shù)生命周期內(nèi),可以獲取和修改Session對象

在請求處理完后,保存此Session變量

可能大家看到sessionkey這個(gè)變量,感覺有些莫名其妙。原因是每次cookie發(fā)送,同樣的站點(diǎn)可能有多個(gè)框架需要使用此cookie頭字段,比如php,aspx,jsp等都是需要使用了,為了好像不要沖突,大家各自使用cookie頭字段內(nèi)各自的key/value對即可。比如php的key默認(rèn)是phpsessid,express-session默認(rèn)的是connect.sid。

總結(jié)

此代碼演示了最基礎(chǔ)的Session的概念,但是遠(yuǎn)遠(yuǎn)不是一個(gè)可用的模塊,想要真實(shí)世界中使用的Session模塊,可以考慮express-session。

實(shí)現(xiàn)一個(gè)真正可以的會話,還需要考慮很多問題:

本文中使用是Session Id其實(shí)就是一個(gè)自增的整數(shù)。這會導(dǎo)致客戶端欺騙,黑客可以猜到SessionID,使用偽造的SessionID獲得服務(wù)器內(nèi)對應(yīng)的狀態(tài)數(shù)據(jù),或者偽造登錄從而獲得更高權(quán)限。真實(shí)的產(chǎn)品,一般是創(chuàng)建一個(gè)保證唯一的,不易猜測出來的字符串。

本文中的Session每次end后會必然保存,而不管此Session是否修改。實(shí)際的產(chǎn)品,是需要考慮此優(yōu)化的。同時(shí),也需要考慮到Session的失效期,到了失效期就會銷毀,因?yàn)橛行┛蛻艨赡軄硪淮蝺纱我埠笤僖膊粊碓L問了,沒有必要為他們保存狀態(tài)信息,如果再來了,不妨重新創(chuàng)建會話即可。

本文的Session保存在內(nèi)存中,一旦重啟,所有會話都會丟失。實(shí)際產(chǎn)品中,是需要支持持久化的保存的,比如保存到mysql數(shù)據(jù)庫內(nèi),redis內(nèi),mongodb內(nèi)等等。因此需要數(shù)據(jù)持久化的多提供者的方案。

更多的考量,可以去通過閱讀express-session來獲得。本文閱讀完畢,本身就是可以成為閱讀express-session的基礎(chǔ)材料的。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/94638.html

相關(guān)文章

  • SegmentFault 技術(shù)周刊 Vol.16 - 淺入淺出 JavaScript 函數(shù)式編程

    摘要:函數(shù)式編程,一看這個(gè)詞,簡直就是學(xué)院派的典范。所以這期周刊,我們就重點(diǎn)引入的函數(shù)式編程,淺入淺出,一窺函數(shù)式編程的思想,可能讓你對編程語言的理解更加融會貫通一些。但從根本上來說,函數(shù)式編程就是關(guān)于如使用通用的可復(fù)用函數(shù)進(jìn)行組合編程。 showImg(https://segmentfault.com/img/bVGQuc); 函數(shù)式編程(Functional Programming),一...

    csRyan 評論0 收藏0
  • 信安 - 收藏集 - 掘金

    摘要:咱媽說別亂點(diǎn)鏈接之淺談攻擊閱讀掘金作者馬達(dá)編輯迷鹿馬達(dá),精通開發(fā)開發(fā),擅長接口設(shè)計(jì)以及平臺化建設(shè),獨(dú)自主導(dǎo)過多個(gè)產(chǎn)品。一題目購物應(yīng)用分環(huán)境要求安全學(xué)習(xí)資料匯總掘金安全學(xué)習(xí)資料匯總安全學(xué)習(xí)網(wǎng)站收集 咱媽說別亂點(diǎn)鏈接之淺談 CSRF 攻擊 - 閱讀 - 掘金作者 | 馬達(dá)編輯 | 迷鹿 馬達(dá), 精通PHP開發(fā)、Web開發(fā),擅長api接口設(shè)計(jì)以及平臺化建設(shè),獨(dú)自主導(dǎo)過多個(gè)Web產(chǎn)品。目前就職...

    lushan 評論0 收藏0
  • 安全攻防戰(zhàn) - 收藏集 - 掘金

    摘要:咱媽說別亂點(diǎn)鏈接之淺談攻擊閱讀掘金作者馬達(dá)編輯迷鹿馬達(dá),精通開發(fā)開發(fā),擅長接口設(shè)計(jì)以及平臺化建設(shè),獨(dú)自主導(dǎo)過多個(gè)產(chǎn)品。一題目購物應(yīng)用分環(huán)境要求安全學(xué)習(xí)資料匯總掘金安全學(xué)習(xí)資料匯總安全學(xué)習(xí)網(wǎng)站收集 咱媽說別亂點(diǎn)鏈接之淺談 CSRF 攻擊 - 閱讀 - 掘金作者 | 馬達(dá)編輯 | 迷鹿 馬達(dá), 精通PHP開發(fā)、Web開發(fā),擅長api接口設(shè)計(jì)以及平臺化建設(shè),獨(dú)自主導(dǎo)過多個(gè)Web產(chǎn)品。目前就職...

    chanthuang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<