设为首页 收藏本站
查看: 712|回复: 0

[经验分享] NODEJS项目实践0.4 [domain,pm2,log4js,md5]

[复制链接]

尚未签到

发表于 2017-2-22 07:45:13 | 显示全部楼层 |阅读模式
  ###一、前言
  ⋅⋅⋅上节我们基于mongo数据存取的操作,实现了用户注册、登录、退出功能,并应用了初级的权限验证。本节将处理nodejs异常情况、加密、日志及进程守护。
  #####git : https://github.com/xiaolulu/mynodejs.git
  ###二 、MD5
  ⋅⋅⋅密码作为用户登录唯一凭证,其安全性不言而喻,前面我们的密码操作存在两个问题
  ⋅⋅⋅a、用户登录及注册都使用了明文密码
  ⋅⋅⋅b、数据库保存了用户的明文密码
  ⋅⋅⋅常规可以使用二次加密,即前台传递到后台的密码先加密一次,后台再加密一次后存入数据库。
  ####1、客户端加密
  ⋅⋅⋅下载 md5.js 文件,用require包下。可以到我的git上下载,也是网上找的,加了require
  ⋅⋅⋅该文件较稳定且与业务无关,我们放到 root/static/core/js内
  ⋅⋅⋅在root/static/module/issue/register.js里引用,在password传输前对其加密
  ```javascript
  require.config({
  baseUrl: basePath,
  paths: {
  all: 'public/js/all',
  md5: 'core/js/md5'//引用md5
  }
  })
  define( ['md5','all'], function( md5 ){
  $( '#registerForm' ).on( 'submit', function(){
  var data = {
  username: $('#username').val(),
  password: md5.hex_md5( $('#password').val() ),//对password加密
  email: $('#email').val()  
  }
  $.ajax
  ...
  })
  });
  ```
  ⋅⋅⋅此时通过mongo终端可以看到新注册的密码已经变成32的加密字段如
  ⋅⋅⋅123456 → 'e10adc3949ba59abbe56e057f20f883e'
  ####2、服务器端加密
  ⋅⋅⋅在添加注册数据到数据库的时候,再加密一次
  ⋅⋅⋅nodejs包装的加密模块为 crypto,通过package.json安装
  ⋅⋅⋅对用户数据存取都在root/web/controls/user.js,我们对其修改
  ```javascript
  var db = require( '../db/sql' ),
  crypto = require( 'crypto' );//引入  crypto 模块
  var md5 = function(data) { //定义加密函数
  return crypto.createHash('md5').update(data).digest('hex').toLowerCase();  
  } 
  function addUser( req, res ){
  var data = req.body;
  data.password = md5( data.password );//对存入的密码加密
  ...
  }
  function findUser( req, res ){
  var data = req.body;
  data.password = md5( data.password );//对查询的密码加密
  ...
  }
  ...
  ```
  ⋅⋅⋅此时我们再看数据库里的同样的密码,变化为另外一种32位的密文
  ⋅⋅⋅如 123456 → '14e1b600b1fd579f47433b88e8d85291'
  ⋅⋅⋅再执行一次注册 / 登录,功能是同样可用的,但密码已经是安全的了。
  ⋅⋅⋅此时我们完成了加密,之所以二次加密是因为,客户端加密防止在向服务器传送的过程中被拦截,服务器再加密是防止内部出错。
  ###三 、nodejs异常处理
  ⋅⋅⋅开发程序难免会出现代码异常,前台js情况还好些,通常只影响当前用户的当前页面,但服务器如果出现异常,则要严重的多,处理不慎会造成整个项目的崩溃,停止服务,所以后台的异常处理要非常全面。
  ⋅⋅⋅js出提供了异常处理机制,就是我们常用的try{}catch(e){},nodejs也可以使用
  ####1、同步异常处理
  ⋅⋅⋅编辑 root/web/routes/index.js,app.use是所有请求的入口,对其做下包装即可,在第二步中展示
  ####2、异步异常处理
  ⋅⋅⋅nodejs最主要的优势在于其非阻塞的IO机制,意味着其内有大量的异步回调,这里的错误是难以捕捉和处理的,也是try..catch所无法达到的,nodejs提供了domain方法,同样在 app.use里做处理
  ```javascript
  …
  var domain = require( 'domain' );//引入domain
  var Domain = domain.create();
  Domain.on( 'error', function( e ){//监听异步错误
  console.log( 'error ' + e) 
  });
  …
  app.use( function( req, res, next){
  try{
  if( privilege[ req.path ] && req.path != '/login' && !req.session.status ){
  if( req.method == 'GET' ){
  res.redirect('/login');
  } else {
  res.send( { code: 1001, msg: 'need you to log in'})    
  }           
  } else {
  Domain.run( function(){
  next();//包装异步处理,这样回调出错,也不会造成项目崩溃
  });
  }
  } catch( e ){
  res.redirect( '/' );
  }
  });
  ```
  ###四、pm2
  ⋅⋅⋅在上一步我们做了异常处理,可以减少项目崩溃的机率,但其还是不够稳妥,下面我们使用进程守护模块。
  ⋅⋅⋅pm2及forever模块是目前较常用的nodejs进程守护模块,前者更常用些、功能也更强大(提供负载)。其原理主要是pm2开启一个主进程,另行再开子进程运行nodejs项目,主进程监听子进程,若子进程崩溃,pm2会自行将其启动,并且也可以对一个项目启动多个子进程,pm2主进程做随机转发请求。
  ####1、安装 npm install pm2 -g
  ⋅⋅⋅其类似于前面我们安装的node-dev,是用于启动项目的,所以要安装在全局
  ####2、常用命令
  ```javascript
  pm2 start app.js//启动
  pm2 ls//显示已启动的项目进程,会显示项目id / name 负载等信息
  pm2 start app.js -i max //自动依赖电脑内核数,尽量启动多的进程
  pm2 reload all//重新加载
  pm2 restart [ app_name | id | all ]//重启项目,用于改了nodejs代码时,其不具备node-dev功能
  pm2 stop  [ app_name | id | all ]//停止某进程
  pm2 logs
  ```
  ###五、log4js
  ⋅⋅⋅后台项目日志是极其重要的,后端不是客户端 js那么明晰,错误可以随时debug,日志是很好的记录,其对所有数据的请求进行记录,也记录了出现危害项目的行为,如修改、删除数据操作。
  ⋅⋅⋅我们使用log4js模块,通过package.json安装
  ⋅⋅⋅在root/web下新建log文件夹存放日志文件
  ⋅⋅⋅log4js还是需要一些简单的配置,前面使用md5及后面会到诸如ip获取等也需要一些简单的配置,我们将这些简单的不需要单独成一个文件的配置都放是一个文件里,新建 root/web/tool/gadget.js,添加代码如下
  ```javascript
  var log4js = require( 'log4js' );
  //引入log4js
  var logConfig = {
  //设置配置项
  "appenders":[
  {"type": "console","category":"console"},
  {
  "type": "dateFile",
  "filename":"./log/",
  //目录
  "pattern":"yyyyMMdd.log",
  //命名规则,我们是按天,也可以设置为yyyyMMddhh.log,为按时
  "absolute":true,
  "alwaysIncludePattern":true,
  "category":"logInfo"
  }
  ],
  "levels":{"logInfo":"DEBUG"}
  }
  log4js.configure( logConfig );
  var logInfo = log4js.getLogger('logInfo');
  module.exports = {
  logInfo: logInfo
  }
  ```
  ⋅⋅⋅我们对所有的请求作记录,在root/web/routes/index.js,里的app.use处添加日志记录
  ```javascript
  var gadget = require( '../tool/gadget' );
  ….
  app.use( function( req, res, next){
  console.log( req.path );  
  gadget.logInfo.info( req.path );
  //添加日志,记录所有请求路径
  try{
  if( privilege[ req.path ] && req.path != '/login' && !req.session.status ){
  console.log( req.session.status );
  if( req.method == 'GET' ){
  res.redirect('/login');
  } else {
  res.send( { code: 1001, msg: 'need you to log in'})    
  }           
  } else {
  Domain.run( function(){
  next();
  });
  }
  } catch( e ){
  gadget.logInfo.error( req.path );
  //添加日志,记录出错信息
  res.redirect( '/' );
  }
  })
  ```
  ⋅⋅⋅项目启动后,可以看到root/web/log下自动新增了 20150723.log文档,具体文件名视当前日期而定。
  ⋅⋅⋅访问我们的站点的任一个页面,日志文件中都会自动多出相应的记录。
  ⋅⋅⋅实时查看文档Linux下可用 tail -f 20150723.log,终端其会自动刷新目录数据。
  ⋅⋅⋅本页的 Domain.on( 'error' )回调里也添加logInfo.error。还有DB的存取等所以有意义的数据往返及操作都可以记录下来
  ###六、总结
  ⋅⋅⋅本节我们主要是对nodejs模块的应用,处理异常( domain)、加密了数据(md5)、设置进程守护(pm2) 并 做了日志记录(log4js),每一块只对基础配置使用做了介绍,后面再单独出一章详细nodejs常用模块
  ⋅⋅⋅近来工作较忙,就先写到这里,下节演示nodejs分成前后台两部分接收页面请求及DB存取、git操作
  #####其它案例可参见: http://www.upopen.cn
  ###全栈工程 - 技术新Q群:435485569

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-345391-1-1.html 上篇帖子: 一起做开源在线IDE(mokide=nodejs+jQueryUI+CodeMirror) 下篇帖子: nodejs,go还不成熟,我还是用py
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表