一、前言

⋅⋅⋅书接上回,我们搭建了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的操作,添加如下代码

javascript        var mongoose = require( 'mongoose'  ); //引用模块mongoose.connect( 'mongodb://127.0.0.1/myDB', function( err ){//连接mongoose,连接本地127.0.0.1,mongo的默认端口是 27017if( !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,用于处理路由与数据存储的中间逻辑,添加代码如下

javascript        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函数改为
javascript        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如下

javascript        var issue = require( './issue' ),session = require( 'express-session' ); //添加 express-session引用exports.all = function( app ){app.use( session({ //配置sessionresave: false,saveUninitialized: false,secret: 'upopen'}))app.use( function( req, res, next){if( req.path != '/login' && !req.session.status ){ //判断session状态是否是trueres.redirect('/login'); //不是则跳转到登录页} else {next(); //为true,则继续执行其请求}})app.get( '/', function( req, res ){issue.index( req, res );});…

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

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

javascript        …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。

⋅⋅⋅cookie使用,可参考 http://www.upopen.cn/article/info?id=559e2cbda46ee1885f000002

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

8、权限设置

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

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

javascript        module.exports = {'/user/center' : 1,'/user/info': 1,'/user/blog': 1}

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

javascript        …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,是不能直接redirectres.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

javascript         ...app.get('/logout', function( req, res ){req.session.status = false; //设置session状态为未登录res.setHeader("Set-Cookie","username=null;" ); //清除cookieres.redirect( '/' ); //跳转到首页})...

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

⋅⋅⋅本节我们主要完成:

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

⋅⋅⋅2、通过session保存登录状态

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

⋅⋅⋅4、增加权限判断

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

⋅⋅⋅下节主要实现:

⋅⋅⋅1、注册时的邮件验证

⋅⋅⋅2、redis保存登录状态

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

⋅⋅⋅4、git操作

全栈工程 - 技术新Q群:435485569

上一篇:公司项目NODEJS实践0.2[ express, ajax.. ]

下一篇:待续

公司项目NODEJS实践0.3[ mongo / session ...]相关推荐

  1. nodejs 实践项目_NodeJS:最佳生产实践

    nodejs 实践项目 by Saurabh Rayakwar 通过索拉比·雷阿克瓦尔 NodeJS:最佳生产实践 (NodeJS: Best Practices for Production) Th ...

  2. nodejs 实践:express 最佳实践(五) connect解析

    nodejs 实践:express 最佳实践(五) connect解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固,需 ...

  3. 《全球顶尖公司的领导力实践》——读书随笔

    全球顶尖公司的领导力实践 --读书随笔 1. 前言 1)顶尖公司和领导者发展的基础: a) 顶尖公司的CEO和董事会是领导和激励的源泉; b) 顶尖公司高度关注优秀人才; c) 顶尖公司设计恰当的领导 ...

  4. 软件项目最佳实践: 可编程的权限控制

    续 软件项目最佳实践: 又谈权限管理 当我们面对复杂的权限控制一愁莫展时,因为未来不明确需求而烦恼时,我们期望项目的权限控制是可编程的,但手中的代码不堪入目,只能暗自发誓接手下一个新项目时,一定重新设 ...

  5. Anytime项目开发记录0

    Anytime,中文名:我很忙. 开发者:孤独的猫咪神. 这个项目会持续更新,直到我决定不再维护这个APP. 2014年3月10日:近日有事,暂时断更.希望可以会尽快完事. 2014年3月27日:很抱 ...

  6. 第 28 小时项目管理过程实践和案例分析

    第 28 小时项目管理过程实践和案例分析 根据考试大纲,这部分作为下午 考试的内容,共有 3 道大题,每题 25 分,共 75 分,45 分及格.考题形式为"计算+项目管理有关知识" ...

  7. flask python web开发 可视化开发_Python + Flask 项目开发实践系列六

    今天开始我们讲讲Flask Web实践项目开发中的查看详情功能是如何实现的. Step1:html 部分 lists +="<tr>"+ //拼凑一段html片段 &q ...

  8. nodejs 实践:express 最佳实践(六) express 自省获得所有的路由

    nodejs 实践:express 最佳实践(六) express 自省获得所有的路由 某些情况下,你需要知道你的应用有多少路由,这在 express 中没有方法可以.因此我这边曲线了一下,做成了一个 ...

  9. python web开发项目 源码_Python + Flask 项目开发实践系列七

    对于 Python + Flask 这种灵活的web开发框架,在前面的六个系列文章中详细的进行了说明,主要讲到了页面的首页加载时的页面渲染,增加功能,删除功能,修改功能,查询功能,查询详情功能等一些页 ...

最新文章

  1. 【2556】传说中的数据结构 sdutOJ
  2. python批量上传 服务器_Python Tornado批量上传图片并显示功能
  3. AUTOSAR从入门到精通100讲(四十八)-Lin通信协议栈分析两步走-LinTrcvLIN Driver
  4. 小程序 graphql_GraphQL应用程序中的五个常见问题(以及如何解决)
  5. TCP/IP分析(一) 协议概述
  6. linux下如何做ghost,又简单又方便,很实用的方法!!!
  7. MIP 扩展组件开发手册
  8. iTOP-4418开发板支持动态调频,AXP228电源管理,预留锂电池接口,内置充放电电路及电量计...
  9. vue改变标签属性_Vue用v-for给循环标签自身属性添加属性值的方法
  10. 漫画 | 如果面试时大家都说真话…
  11. 一个空格惹的祸:服务器端接收不到前端采用问号传参方式传过来的值
  12. oracle英文怎么转中文,ORACLE英文字符集转中文
  13. 倍福EtherCAT EK1100耦合器技术参数
  14. Hadoop 安全模式永久退出的方法
  15. powerdesigner错误提示实体属性名称唯一性_WPS导致加载DLL错误的解决方案
  16. 欢迎查看Vue总结知识
  17. 【MySQL】表数据的增删查改(DML)
  18. 马晶(MaJing)论文总结
  19. Web 应用安全发展的介绍
  20. 对接支付宝支付,沙箱环境提示:支付存在钓鱼风险!防钓鱼网站的方法

热门文章

  1. (003) java后台开发之设置Eclipse代码提示和快捷键
  2. linux脚本 程序输入,[转]Linux中shell脚本如何自动输入…
  3. Dell服务器配置RAID1+RAID0磁盘阵列
  4. 在线网上打字系统_在线网上打字比赛软件_打字练习_中英文打字系统
  5. FMDatabase常见的几个操作
  6. 云服务器ECS挖矿木马病毒处理和解决方案
  7. mysql 服务启动异常
  8. QT编译发布程序后报错如缺少dll、“应用程序无法正常启动(0xc000007b)”的可能解决方法
  9. Keil 5出现Error: L6218E: Undefined symbol解决方法
  10. jupyter notebook dead kernel问题解决