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

資訊專(zhuān)欄INFORMATION COLUMN

Session原理、安全以及最基本的Express和Redis實(shí)現(xiàn)

Airmusic / 1861人閱讀

摘要:基于以上原因,很多管理都是基于實(shí)現(xiàn)的。在經(jīng)過(guò)中間件的時(shí)候就會(huì)自動(dòng)完成的有效性驗(yàn)證延期重新頒發(fā)以及對(duì)中數(shù)據(jù)的獲取了。上述代碼只是對(duì)于請(qǐng)求的靜態(tài)處理,整個(gè)用戶(hù)管理的另一個(gè)方面則是狀態(tài)的切換用戶(hù)的登陸登出以及用戶(hù)數(shù)據(jù)的獲取。

基礎(chǔ)概念

Session管理是Web Application的基礎(chǔ)也是一個(gè)老生常談的話題。為了方便后文的展開(kāi),更重要的是確認(rèn)自己清晰的理解了整個(gè)Session管理的概念,我在此還是決定贅述的整個(gè)流程。如果你已經(jīng)對(duì)于Session概念非常清晰的話,可以跳過(guò)本節(jié)不影響對(duì)于后文的理解。

HTTP協(xié)議在設(shè)計(jì)的時(shí)候是無(wú)狀態(tài)的。這是一個(gè)很關(guān)鍵的概念,意味著服務(wù)器在處理請(qǐng)求的時(shí)候,并不關(guān)注這個(gè)請(qǐng)求是誰(shuí)發(fā)來(lái)的。這對(duì)于以提供內(nèi)容為核心的Web1.0,例如門(mén)戶(hù)網(wǎng)站,非常適合。然而對(duì)于以應(yīng)用服務(wù)為核心的Web 2.0而言,服務(wù)器端必須有能力從請(qǐng)求中提取出請(qǐng)求者的身份信息,以在請(qǐng)求者不用反復(fù)輸入身份的情況下,提供連續(xù)的服務(wù)。

實(shí)現(xiàn)請(qǐng)求身份驗(yàn)證的方式很多,其中一種廣泛接受的方式是使用服務(wù)器端產(chǎn)生的Session ID結(jié)合瀏覽器的Cookie實(shí)現(xiàn)對(duì)Session的管理,一般來(lái)說(shuō)包括以下4個(gè)步驟:

服務(wù)器端的產(chǎn)生Session ID

服務(wù)器端和客戶(hù)端存儲(chǔ)Session ID

從HTTP Header中提取Session ID

根據(jù)Session ID從服務(wù)器端的Hash中獲取請(qǐng)求者身份信息

上圖是一個(gè)使用Redis Cluster來(lái)實(shí)現(xiàn)對(duì)Session管理的流程,但本質(zhì)上除了redisMatrix.get和redisMatrix.set以外,和一般的Session管理流程是一致的。

簡(jiǎn)單來(lái)說(shuō),一個(gè)請(qǐng)求到達(dá)的時(shí)候,服務(wù)器會(huì)先判斷是否帶有Session信息。如果有,則根據(jù)Session ID去數(shù)據(jù)庫(kù)中查找是否具有對(duì)應(yīng)的用戶(hù)身份信息。此處可能會(huì)出現(xiàn)Session失效、非法的Session信息等可能性,那么服務(wù)器視同無(wú)Ssession信息的情況,重新的產(chǎn)生一個(gè)隨機(jī)的字符串,并且在Http返回頭中寫(xiě)入新的Session ID信息。另一者,如果服務(wù)器成功獲取了用戶(hù)的身份信息則以該身份為請(qǐng)求者提供服務(wù)。

使用Express和Redis對(duì)Session管理的實(shí)現(xiàn)

Redis是一個(gè)非常適合用于Session管理的數(shù)據(jù)庫(kù)。第一,它的結(jié)構(gòu)簡(jiǎn)單,key-value的形式非常符合SessionID-UserID的存儲(chǔ);第二,讀寫(xiě)速度非???;第三,自身支持?jǐn)?shù)據(jù)自動(dòng)過(guò)期和清除;第四,語(yǔ)法、部署非常簡(jiǎn)單?;谝陨显颍芏郤ession管理都是基于Redis實(shí)現(xiàn)的。
Express已經(jīng)將Session管理的整個(gè)實(shí)現(xiàn)過(guò)程簡(jiǎn)化到僅僅幾行代碼的配置的地步了,你完全不用理解整個(gè)session產(chǎn)生、存儲(chǔ)、返回、過(guò)期、再頒發(fā)的結(jié)構(gòu),使用Express和Redis實(shí)現(xiàn)Session管理,只要兩個(gè)中間件就足夠了:

express-session

connect-redis

廢話不多說(shuō)還是上代碼:

var express = require("express");
var session = require("express-session");
var RedisStore = require("connect-redis")(session);

var app = express();
var options = {
     "host": "127.0.0.1",
     "port": "6379",
     "ttl": 60 * 60 * 24 * 30,   //Session的有效期為30天
};

// 此時(shí)req對(duì)象還沒(méi)有session這個(gè)屬性
app.use(session({
     store: new RedisStore(options),
     secret: "express is powerful"
}));
// 經(jīng)過(guò)中間件處理后,可以通過(guò)req.session訪問(wèn)session object。比如如果你在session中保存了session.userId就可以根據(jù)userId查找用戶(hù)的信息了。

req在經(jīng)過(guò)session中間件的時(shí)候就會(huì)自動(dòng)完成session的有效性驗(yàn)證、延期/重新頒發(fā)、以及對(duì)session中數(shù)據(jù)的獲取了。

上述代碼只是對(duì)于請(qǐng)求的Session靜態(tài)處理,整個(gè)用戶(hù)管理的另一個(gè)方面則是狀態(tài)的切換(用戶(hù)的登陸、登出)以及用戶(hù)數(shù)據(jù)的獲取。

exports.signin = function(params, req, res){
    var username = params.username;
    var password = params.password;

    //查找用戶(hù)信息,看是否滿足登陸條件
    var user = findUser(username, password);
    if(user){
        //成功獲取用戶(hù)對(duì)象
        req.session.regenerate(function(){
            req.user = user;
            req.session.userId = user.id;
            req.session.save();  //保存一下修改后的Session

            res.redirect("/account");
        });  
    }
    else{
        //用戶(hù)信息不符合,登陸失敗
    }
}

exports.signout = function(req, res){
    req.clearCookie("connect.sid");
    req.user = null;

    req.session.regenerate(function(){
        //重新生成session之后后續(xù)的處理
        res.redirect("/signin");
    })
}

exports.persist = function(req, res, next){
    var userId = req.session.userId;

    //通過(guò)user id去數(shù)據(jù)庫(kù)里面查找User對(duì)象
    var user = findUserById(userId);

    if(user){
        req.user = user;
        next();
    }
    else{
        //該用戶(hù)不存在
    }
}
Session的安全問(wèn)題

SessionId就如同請(qǐng)求者的身份證,一旦被攻擊者惡意獲得,攻擊者便可以偽裝成請(qǐng)求者對(duì)服務(wù)器發(fā)起請(qǐng)求,也就是我們經(jīng)常聽(tīng)到的會(huì)話劫持(Session/Cookie Hijack)
關(guān)于會(huì)話劫持的原理推薦大家去看這篇文章

基于上述實(shí)現(xiàn)方法的Session管理,我認(rèn)為基本上可以排除

暴力破解SessionId

惡意植入固定SessionId

兩種可能,因?yàn)閡id的庫(kù)基本上可以保證SessionId的隨機(jī)性;而傳遞SessionId則依賴(lài)HTTP請(qǐng)求頭中的Cookie信息而非URL,同時(shí)在用戶(hù)登錄立刻更換SessionId。

唯一的可能性來(lái)源于Session的監(jiān)聽(tīng),而對(duì)于這種攻擊有效的兩種防止辦法是:

Https
很多網(wǎng)站僅僅在Login的階段使用Https防止用戶(hù)的用戶(hù)名、密碼信息被監(jiān)聽(tīng)者獲取,但是隨后的SessionId同樣有可能被監(jiān)聽(tīng)者獲取而偽造登錄者的身份信息。因此更加推薦的方式是所有的信息傳遞全部使用Https實(shí)現(xiàn),這樣即使監(jiān)聽(tīng)著截獲了信息也無(wú)法破解其中的內(nèi)容。關(guān)于如何使用NodeJS建立一個(gè)HTTPS的server可以參考《HTTPS的原理和NodeJS的實(shí)現(xiàn)》 這篇文章

httpOnly
Express在options中提供了httpOnly的屬性,此屬性默認(rèn)值為true,這個(gè)屬性保證了Cookie的信息不能夠通過(guò)JavaScript腳本獲取。

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

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

相關(guān)文章

  • Express.js?中 Sessions 如何工作?(譯)

    世界上任何一個(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 modul...

    Hydrogen 評(píng)論0 收藏0
  • node中session

    摘要:當(dāng)會(huì)話過(guò)期或被放棄后,服務(wù)器將終止該會(huì)話。原來(lái)中間件生成的是一個(gè)對(duì)象,里面包含了信息。這個(gè)有一個(gè)過(guò)期時(shí)間,比如,上面代碼中設(shè)置的是小時(shí)。也就是說(shuō),小時(shí)后,這個(gè)在瀏覽器中會(huì)自動(dòng)消失。 前言 在上一篇中node中的cookie,對(duì)cookie進(jìn)行了相關(guān)介紹,本篇將繼續(xù)前行,對(duì)session進(jìn)行說(shuō)明。 session是什么 session不就是會(huì)話嘛,那什么是會(huì)話呢?會(huì)話是一個(gè)比連接粒度更大...

    yankeys 評(píng)論0 收藏0
  • node中session

    摘要:當(dāng)會(huì)話過(guò)期或被放棄后,服務(wù)器將終止該會(huì)話。原來(lái)中間件生成的是一個(gè)對(duì)象,里面包含了信息。這個(gè)有一個(gè)過(guò)期時(shí)間,比如,上面代碼中設(shè)置的是小時(shí)。也就是說(shuō),小時(shí)后,這個(gè)在瀏覽器中會(huì)自動(dòng)消失。 前言 在上一篇中node中的cookie,對(duì)cookie進(jìn)行了相關(guān)介紹,本篇將繼續(xù)前行,對(duì)session進(jìn)行說(shuō)明。 session是什么 session不就是會(huì)話嘛,那什么是會(huì)話呢?會(huì)話是一個(gè)比連接粒度更大...

    fredshare 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<