⋅⋅⋅书接上回,咱们搭建了WEB服务端路由、模板等功能,完成了register 经过ajax与后端的通讯,今天主要完成数据与mongodb的存取,实现注册 / 登陆 / 退出功能javascript
⋅⋅⋅DEMO GIT https://github.com/xiaolulu/mynodejs.gitcss
⋅⋅⋅上一节咱们已经安装过了mongo,本节主要是对其操做前端
⋅⋅⋅nodejs对 mongo的操做,咱们使用 mongoose库java
⋅⋅⋅在package.json添加mongoose,并npm installnode
⋅⋅⋅使用参考http://www.upopen.cn/article/info?id=559688a7f0e6e0665b000004git
javascriptvar 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 }
javascriptvar 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 }
四、修改上节在/root/web/routes/issue.js定义的register函数改成
javascript
function registerUser( req, res ){ user.addUser( req, res ); }
⋅⋅⋅并增长 /web/controls/user.js的引用github
⋅⋅⋅再用node-dev启动项目,访问register,提交表单,能够看到返回成功,至此咱们注册用户成功web
⋅⋅⋅打开shell,执行mongo,打开mongo终端ajax
⋅⋅⋅执行use myDB //切换到myDB数据库redis
⋅⋅⋅执行db.User.find().pretty() //能够看到刚才咱们新增的数据
⋅⋅⋅在/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 流程便可。
⋅⋅⋅上一步,咱们走通了注册和登陆查询功能,而后登陆的目的是为了根据用户登陆与否判断是否具有访问某些页面的权限。
⋅⋅⋅这里简单说下session(后面再单独详解):网站保存信息或状态,页面端经常使用的是cookie,而对应服务端是session,登陆状态须要保存服务端以防伪造页面端。而http(后面再单独详解)是无状态的,为使页面端与服务端关联,生成session时,同时会在cookie里写入一个对应的id值,如 session_sid,每次页面与服务器的交互都会自动带上cookie,服务器端会据这个id查找是否有对应的session保存,从而造成状态保存。
⋅⋅⋅这里咱们也使用第三方库 express-session,安装同 mongoose
⋅⋅⋅在 /root/web/routes/index.js里引入 express-session,并新增app.use以下
javascriptvar 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函数下新增以下代码
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,便可。
⋅⋅⋅上一步,增长了页面请求对权限登陆的验证,可是验证只是针对某些页面的,咱们把须要验证的路径罗列下来。
⋅⋅⋅在/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,是不能直接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下的三个页面都须要登陆。
⋅⋅⋅在/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;" ); //清除cookie res.redirect( '/' ); //跳转到首页 }) ...
⋅⋅⋅本节咱们主要完成:
⋅⋅⋅一、经过mongoose来操做mongo,完成数据增长和查询
⋅⋅⋅二、经过session保存登陆状态
⋅⋅⋅三、完成注册 / 登陆 / 退出
⋅⋅⋅四、增长权限判断
⋅⋅⋅本节咱们虽然使用了session来记录登陆状态,但实际使用时仍是会有些问题,session是保存在本项目里的,若是上线后web服务端须要用多台计算机来负载,则状态不能共享。能够采用搭建验证服务器,即单独配置一个服务器来执行验证功能,也可使用redis来保存登陆状态。下节咱们将使用redis来保存登陆状态。
⋅⋅⋅下节主要实现:
⋅⋅⋅一、注册时的邮件验证
⋅⋅⋅二、redis保存登陆状态
⋅⋅⋅三、nodejs异常处理,同步 and 异步
⋅⋅⋅四、git操做