• 扩展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,如下图:

      至于解密的代码我就不贴出来了,相对于加密过程而言,解密就是倒着来的。

      那么今天的内容就到这里了,感谢各位,如有错误请指出,谢谢! 源代码在此

  • 相关阅读:
    BZOJ 1096: [ZJOI2007]仓库建设
    【BZOJ1008】越狱(排列组合计数,容斥原理)
    【BZOJ1403】Divisibility Testing(数论)
    【BZOJ1225】求正整数(数论)
    高精度模板(From JCVB)
    【NOIP模拟&POJ2152】灰色的果实(树形DP)
    【BZOJ2560】串珠子(状压DP,容斥原理)
    【POJ1185】炮兵阵地(状压DP)
    【POJ3254】Corn Fields(状压DP)
    【POJ3311】Hie with the Pie(状压DP,最短路)
  • 原文地址:https://www.cnblogs.com/ahl5esoft/p/3091992.html
Copyright © 2020-2023  润新知