擴展nodejs簡易mvc之cookie與表單認證


  前段時間使用nodejs實現了簡單的mvc,最近一直在使用nodejs圍繞着這個簡易的mvc進行擴展,力求使其成為一個完整的mvc框架。在http請求中,由於http是沒有狀態的,為了讓客戶端保留一些來自服務端的信息,並且在下一次請求中能傳遞到服務端,那么我們能使用的手段大致分為兩種:1、Cookie;2、胖Url。

  Cookie是絕佳的客戶端存儲介質,也是實現持久會話的最好方式,Cookie主要分為2種:會話Cookie(用戶退出瀏覽器時,會話Cookie會被刪除)和持久Cookie(生存時間更長一些,它們存儲與硬盤上,瀏覽器退出,計算機重啟它們仍然存在)。具體關於Cookie的介紹可以參考司徒正美關於Cookie的文章

  nodejs中添加cookie的應用,我參考了C#的實現方式,在http請求中,Request對象負責管理來自客戶端的Cookie而Response對象則應該負責輸出服務端新增的Cookie,大致代碼如下:

function HttpCookie(cookie) {
    this.hashtable = {};
    var _this = this;
    //分解http請求內的cookie,其格式為 name=value; name=value; ...
    cookie && cookie.split(';').forEach(function (c) {
        var pair = c.split('=');
        _this.hashtable[pair[0].trim()] = [pair[1].trim(), {}];
    });
};
HttpCookie.prototype.add = function (name, value, options) {
    options || (options = {});
    m_has.call(options, 'path') || (options.path = '/');
    this.hashtable[name] = [value, options];
};
HttpCookie.prototype.remove = function (name) {
    var options = this.hashtable[name] && this.hashtable[name][1] || {};
    options[MAX_AGE] = 0;
};
HttpCookie.prototype.toArray = function () {
    var cookies = [];
    for (var k in this.hashtable) {
        var sb = [];
        sb.push(m_util.format(FORMAT, k, this.hashtable[k][0]));
        var options = this.hashtable[k][1];
        for (var op_k in options) {
            sb.push(m_util.format(FORMAT, op_k, options[op_k]));
        }
        cookies.push(sb.join('; '));
    }
    return cookies;
};
HttpCookie.prototype.get = function (name) {
    return this.hashtable[name] && this.hashtable[name][0] || '';
};

  有了Cookie的支持,那么就可以利用Cookie來存儲用戶登錄后需要存儲的一些用戶數據了,類似於C#中的Request.User對象,大致流程如下:

  按照流程,需要修改requestHandler.js在用戶訪問首頁的時候,應該去判斷客戶端是否存在存放SessionID的Cookie,如果不存在的話,則添加相應的Cookie,那么在下一次用戶登錄請求中,就有了對需要存儲的用戶數據加密的key了,大致代碼如下:

//requestHandler.js
if (route.action) {
    //省略了其他代碼
    if (controller[route.action]) {
        try {
            req.cookie = new HttpCookie(req.headers.cookie);
            res.cookie = new HttpCookie();
            //這里的key為了簡便,設置了123456                                                 
            req.cookie.get(m_config.SESSION) || res.cookie.add(m_config.SESSION, '123456');
            //省略了其他代碼
        }
        catch (e) {
            m_invalidHandler.handle500(req, res);
        }
    }
    else {
        m_invalidHandler.handle404(req, res);
    }
}

//controllerBase.js
this.res.writeHead(200, {
    'Set-Cookie': this.res.cookie.toArray(),
    'Content-Type': m_config.CONTENT_TYPE[contentType]
});
this.res.end(content);

  重新啟動服務,然后訪問地址后,會發現生成了sessionId的cookie,如圖:

  有了sessionID后,接下來就可以對登錄的用戶信息進行加密,然后再存入cookie中,相關的代碼大致如下:

var plaintext = JSON.stringify(data);
var cryped = '';
var cipher = m_crypto.createCipher('blowfish', this.req.cookie.get(m_config.SESSION));
cryped += cipher.update(plaintext, 'utf8', 'hex');
cryped += cipher.final('hex');
this.res.cookie.add(m_config.AUTH, cryped);                                            

  這里使用的crypto的cipher和deciper進行加密和解密,如果對於crypto不了解的,可以查看nodejs關於crypto的相關api,至於加密算法可以通過getCiphers()來查看。

  輸入用戶名並登錄后,查看cookie會發現生成加密的cookie,如下圖:

  至於解密的代碼我就不貼出來了,相對於加密過程而言,解密就是倒着來的。

  那么今天的內容就到這里了,感謝各位,如有錯誤請指出,謝謝! 源代碼在此


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM