成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

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

Airmusic / 1809人閱讀

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

基礎(chǔ)概念

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

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

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

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

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

從HTTP Header中提取Session ID

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

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

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

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

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

express-session

connect-redis

廢話不多說還是上代碼:

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天
};

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

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

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

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

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

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

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;

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

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

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

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

暴力破解SessionId

惡意植入固定SessionId

兩種可能,因為uid的庫基本上可以保證SessionId的隨機(jī)性;而傳遞SessionId則依賴HTTP請求頭中的Cookie信息而非URL,同時在用戶登錄立刻更換SessionId。

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

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

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

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

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

相關(guān)文章

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

    世界上任何一個擁有用戶數(shù)據(jù)的 web 應(yīng)用都必須處理 sessions。作為一名開發(fā)者,我們必須要知道它們是什么以及如何處理它們。在這篇文章中,我想要分享的是: session 是什么? session 如何存儲數(shù)據(jù)? 你如何決定存放 session 數(shù)據(jù)的位置? 在 sessions 工作時,你必須意識到的安全性上的影響有哪些?在一些示例代碼中,我將會運用?session npm modul...

    Hydrogen 評論0 收藏0
  • node中session

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

    yankeys 評論0 收藏0
  • node中session

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

    fredshare 評論0 收藏0

發(fā)表評論

0條評論

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