`
逐行分析JS源代码
  • 浏览: 87982 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

公司项目NODEJS实践0.3[ mongo / session ...]

阅读更多

 

 

http://www.upopen.cn

 

一、前言

        书接上回,我们搭建了WEB服务端路由、模板等功能,完成了register 通过ajax与后端的通信,今天主要完成数据与mongodb的存取,实现注册 / 登录 / 退出功能

        DEMO GIT https://github.com/xiaolulu/mynodejs.git

 

二、db操作

        上一节我们已经安装过了mongo,本节主要是对其操作

 

        1、mongoose

        nodejs对 mongo的操作,我们使用 mongoose库

        在package.json添加mongoose,并npm install

        使用参考http://www.upopen.cn/article/info?id=559688a7f0e6e0665b000004

        

        2、/root/web目录下创建 db/sql.js,用于对mongoose的操作,添加如下代码

        ***********************************************************************************

        var mongoose = require( 'mongoose'  ); //引用模块

        mongoose.connect( 'mongodb://127.0.0.1/myDB', function( err ){

            //连接mongoose,连接本地127.0.0.1,mongo的默认端口是 27017

            if( !err ){

                console.log( 'DB == connect to mongodb' );

            } else {

                throw err;

            }

        } );

        

        var Schema = mongoose.Schema;

        

        var UserSchema = new Schema({ //创建User表模型,数据可据需求增减

            username: String,

            password: String,

            email: String,

            disabled: Boolean, //后面加注册后的邮件验证功能

            date: Date,

            power: Number  //后面会用到权限功能  

        });

        

        var UserModel = mongoose.model( 'User', UserSchema, 'User' );

        

        function initData( data, db ){ //对参数做预处理,以防出现不合要求的参数,后面这块会做扩展

            var query = {};

            for( var key in data ){

                if( db.tree[ key ] ){

                    query[ key ] = data[ key ];

                }

            }

            return query;

        }

        

        function addUser( data, cb ){ //增加用户

            data = initData( data, UserSchema );

            ( new UserModel( data )).save( function( err, doc  ){

                cb( err, doc );

            })

        }

        function findUser( data, cb ){ //查找用户

            data = initData( data, UserSchema );

            UserModel.findOne( data ).exec( function( err, doc ){

                cb( err, doc );

            })

        }

        

        module.exports = {

            addUser: addUser,

            findUser: findUser

        }

        ##########################################################################

        

        3、在 /root/web下新建controls/user.js,用于处理路由与数据存储的中间逻辑,添加代码如下

        ****************************************************************************

        var db = require( '../db/sql' ); //添加前面定义的db操作模块

        

        function addUser( req, res ){ //增加用户

            var data = req.body; //post过来的数据在req.body里,get过来的数据在req.query里

            data.date = new Date(); //数据里增加时间

            db.addUser( data, function( err, doc ){

            if( !err ){

                res.send( { code: 0, msg: 'add User Success', data: doc } );

                //对查询结果返回,返回格式统一为 {code: 返回码, msg: 返回描述, data: 返回值}

                }

            })

        }

        

        function findUser( req, res ){ //查找用户

            var data = req.body;

            db.addUser( data, function( err, doc ){

                if( !err ){

                    res.send(  { code: 0, msg: 'find User Success', data: doc }  );

                }

            })

        }

        

        module.exports = {

            addUser: addUser,

            findUser: findUser

        }

        #########################################################################

        

        4、修改上节在/root/web/routes/issue.js定义的register函数改为

        **********************************************************************************

        function registerUser( req, res ){

            user.addUser( req, res );

        }

        #########################################################

        并增加 /web/controls/user.js的引用

        再用node-dev启动项目,访问register,提交表单,可以看到返回成功,至此我们注册用户成功

 

        5、使用shell mongo

        打开shell,执行mongo,打开mongo终端

        执行use myDB //切换到myDB数据库

        执行db.User.find().pretty() //可以看到刚才我们新增的数据

        

        6、增加登录查询

        在/root/web/views/issue下新建login.ejs,添加登录form。

        在/root/static/module/issue 下新建 login的 js/css/img 静态文件,添加登录请求,如注册。

        我们在db操作/db.sql.js里及业务处理/controls/user.js已经增加查询方法,只需在/routes/index.js 及 issue里增加 登录查询即可,这里不在列出,参考 register 流程即可。

 

        7、session

        上一步,我们走通了注册和登录查询功能,然后登录的目的是为了根据用户登录与否判断是否具备访问某些页面的权限。

        这里简单说下session(后面再单独详解):网站保存信息或状态,页面端常用的是cookie,而对应服务端是session,登录状态需要保存服务端以防伪造页面端。而http(后面再单独详解)是无状态的,为使页面端与服务端关联,生成session时,同时会在cookie里写入一个对应的id值,如 session_sid,每次页面与服务器的交互都会自动带上cookie,服务器端会据这个id查找是否有对应的session保存,从而形成状态保存。

        这里我们也使用第三方库 express-session,安装同 mongoose

        在 /root/web/routes/index.js里引入  express-session,并新增app.use如下

        *********************************************************

        var issue = require( './issue' ),

              session = require( 'express-session' ); //添加 express-session引用

        exports.all = function( app ){

            app.use( session({ //配置session

                resave: false,

                saveUninitialized: false,

                secret: 'upopen'

            }))

            app.use( function( req, res, next){

                if( req.path != '/login' && !req.session.status ){ //判断session状态是否是true

                    res.redirect('/login'); //不是则跳转到登录页

                } else {

                    next(); //为true,则继续执行其请求

                }

            })

            app.get( '/', function( req, res ){

                issue.index( req, res );

            });

        …

        

        上面的代码是对所有的页面做了限制,都必须是登录的状态才能访问,所以前端要先有注册成功的账号,这样的权限设置当然是不对的,我们只是做下测试。

        打开/root/web/controls/user.js,在findUser函数下新增如下代码

        ********************************************************************

        …

        function findUser( req, res ){

        var data = req.body;

            db.findUser( data, function( err, doc ){

                if( !err ){

                    if( doc ){ //如果登录有查找结果

                        req.session.status = true;        //则session里记录状态为true

                    }

                    res.send(  { code: 0, msg: 'find User Success', data: doc }  );

                }

            })

        }

        …

        ####################################################

        

        再打开站点测试,发现,无论是访问index 还是 register都是自动跳转login,登录信息成功后,index和register都可以访问了,查看cookies里的信息,会看到 自动生成的connect.sid(名称可能不同),就是保存关联session的。手动删除connect.sid,所有页面又会都跳转到 login。

        执行退出命令,只要设置req.session.status = false,即可。

        

        8、权限设置

        上一步,增加了页面请求对权限登录的验证,但是验证只是针对某些页面的,我们把需要验证的路径罗列下来。

        在/web/config下新增 privilege.js,用来罗列权限表,我们新增几个用户管理页面,用来表示权限需要

        *****************************************************************

        module.exports = {

            '/user/center' : 1,

            '/user/info': 1,

            '/user/blog': 1

        }

        ##################################################        

        修改 /root/web/routes/index.js,引入/web/config/privilege.js,修改验证是否登录的app.use

        *****************************************

        …

        var privilege = require( '../config/privilege' );

        …

        app.use( function( req, res, next){

            if( privilege[ req.path ] && req.path != '/login' && !req.session.status ){

                //privilege[ req.path ] 判断该路径是否需要登录权限

                if( req.method == 'GET' ){ //如果是get请求

                    res.redirect('/login'); 则执行跳转

                } else { //其它请求,基本都是POST,是不能直接redirect

                    res.send( { code: 1001, msg: 'need you to log in'}); //则返回错误码,提示需要登录

                }

            } else {

                next();

            }

        })

        …

        ##########################################################################

 

        在web/routes 、web/views、status/module,新增对应的用户页面,user/blog,user/info,user/center,添加时注意文件夹的命名及细分。

        清除cookie,再访问 index 、register都是可以的,而user下的三个页面都需要登录。

        

        9、页面登录状态显示 及 退出

        在/root/static/public/js 下新建 all.js,用于所有页面都要执行js

        将页面据cookies判断登录状态的js写入,以便页面导航上 显示 登录 或 退出,通过requirejs,在每个页面引入。

        退出,即给退出链接加一个get请求,/logout,在/routes/index.js里,添加logout

        **************************************************************************************

         ...

        app.get('/logout', function( req, res ){

            req.session.status = false; //设置session状态为未登录

            res.setHeader("Set-Cookie","username=null;" ); //清除cookie

            res.redirect( '/' ); //跳转到首页

        })

        ...

        ##################################################################

 

三、至此我们完成了简单完成了注册及登录功能流程。

        本节我们主要完成:

        1、通过mongoose来操作mongo,完成数据增加和查询

        2、通过session保存登录状态

        3、完成注册 / 登录 / 退出

        4、增加权限判断

 

        本节我们虽然使用了session来记录登录状态,但实际使用时还是会有些问题,session是保存在本项目里的,如果上线后web服务端需要用多台计算机来负载,则状态不能共享。可以采用搭建验证服务器,即单独配置一个服务器来执行验证功能,也可以使用redis来保存登录状态。下节我们将使用redis来保存登录状态。

 

        下节主要实现:

        1、注册时的邮件验证

        2、redis保存登录状态

        3、nodejs异常处理,同步 and 异步

        4、git操作

1
1
分享到:
评论

相关推荐

    linux安装nodejs

    - 检查Node.js和npm的版本:`./node -v` 和 `./npm -v`。注意,由于尚未配置环境变量,需要使用相对路径运行这两个命令。 4. **配置环境变量**: 使用`vi`编辑器打开 `/etc/profile` 文件,追加以下行到文件末尾...

    rh-nodejs14-nodejs-14.17.2-1.el7.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    NodeJs-v18.12.1-x86 Windows安装包

    1. **下载安装包**:访问 https://nodejs.org/en/download/ 或者通过提供的本地资源 `node-v18.12.1-x86.msi` 下载适用于 x86 架构的安装文件。 2. **运行安装程序**:双击下载的 `.msi` 文件,启动安装向导。 3. **...

    windows8.1+iis8.5下安装node.js开发环境

     Nodejs http://www.nodejs.org/download/  iisnode https://github.com/tjanczuk/iisnode/wiki/iisnode-releases  IIS URL Rewrite http://www.iis.net/downloads/microsoft/url-rewrite No.2:安装

    LINUX安装node/nodejs

    https://nodejs.org/zh-cn/download/releases/ 不建议自动安装(版本太老,且冲突) sudo apt -y install npm # 更新的并不是最新的。 sudo npm i npm@latest -g` sudo apt -y install curl curl -sL ...

    nodejs-demo, nodejs演示.zip

    nodejs-demo, nodejs演示 Express3演示Express 3.x 演示( https://github.com/bsspirit/nodejs-demo/tree/express3 )Express 4.x 演示( https://github.co

    jupyter-nodejs, 用于 jupyter/ipython的node.js 内核.zip

    jupyter-nodejs, 用于 jupyter/ipython的node.js 内核 Jupyter NodeJS这是 Jupyter的内核。热的时候拿出来 ! 或者查看示例笔记本。先决条件IPython 3 。xnodeZeroMQpkg配置安装git clone https://github.

    Nodejs 16.14.2 Windows .zip版本 安装可参考:https://blog.csdn.net/ling19

    Node.js 就是运行在服务端的 JavaScript,是一个基于Chrome JavaScript 运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常...

    hudson.plugins.nodejs.tools.NodeJSInstaller 版本最高为17.9.0

    用于解决jenkins安装nodeJs插件后不能选择nodejs版本,将该文件上传到服务器,然后 docker cp ./hudson.plugins.nodejs.tools.NodeJSInstaller 容器ID:/var/jenkins_home/updates 然后重启Jenkins

    gpai:一个简单的nodejs API,可从Google Play获取申请信息

    一个简单的nodejs API,可获取Google Play应用信息 #安装 npm install gpai #API var gpai = require ( 'gpai' ) ; gpai ( { id : "com.urucas.wifime" } ) . then ( function ( info ) { console . log ( ...

    webrtcchatde

    经修改后在本人公司局域网成功运行,试过两个手机和一个笔记本电脑同时视频通信OK。修改和运行步骤: 1. 从http://ishare.iask.sina.com.cn/f/35083616.html下载webrtc.chatdemo.zip,解压缩,修改其中public\...

    [nodejs,js]天气预报,nodejs抓取页面,js正则提取数据

    [nodejs搭建,express框架,nodejs简单页面抓取,JS正则,canvas光晕效果] 在线:http://wangxinsheng.herokuapp.com/weather [heroku服务器访问国内好像很慢。。。所以抓取页面也特别慢] nodejs抓取页面,js正则提取数据

    测试用例正交测试脚本生成

    1)Nodejs 如果你电脑还未安装配置nodejs环境,请参考:https://www.runoob.com/nodejs/nodejs-install-setup.html 下载Nodejs https://npm.taobao.org/mirrors/node/v12.13.0/ (建议版本使用v12.13.0 小于v...

    微信小游戏3D合成消除2048源码

    微信小游戏,3D,合成消除2048。 只用了three.js和cannon.js,没用其它框架。 兼容头条抖音。 仅供学习参考,请不要直接上架发布。 ...https://nodejs.blog.csdn.net/article/details/108920590

    微信小程序-点餐系统(包含前端小程序,后台nodejs及mysql数据库表).zip

    同时使用nodejs编写后台部分来操作数据库,和我一样初学小程序或nodejs的可以在本项目中学习了解关于小程序结构代码,免费,构建等内容,入门小程序及nodejs的好选择。技术栈及工具工具微信开发者工具 vscode mysql...

    win7 安装最后一个支持的nodejs-13.14.0.zip

    Node.js 是一个跨平台的 JavaScript 运行时环境。 Node.js 使用高效、轻量级的事件驱动、非阻塞 I/O 模型。Node.js 的生态系统是目前最大的开源包管理系统。 Node.js 是一套用来编写高性能网络服务器的 JavaScript...

    NWJS(NodeJS)调用小票机demo.zip

    NWJS(NodeJS)调用小票打印机,实现打印小票功能 项目介绍:https://blog.csdn.net/u012383839/article/details/106988705?spm=1001.2014.3001.5502

    nodejs 的 imagemin.min.js 模块压缩版,无需安装环境直接使用

    let imageminApi = require('../lib/imagemin.min') // 压缩图片 imageminApi.imagemin(['dir/image.png',...], { plugins: [ imageminApi.imageminMozjpeg({ quality: rate //压缩质量(0,1) }), ...

    rh-nodejs12-npm-6.14.13-12.22.2.1.el7.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    rh-nodejs10-npm-6.14.4-10.21.0.3.el7.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

Global site tag (gtag.js) - Google Analytics