Nodejs后端开发(五)-小知识整理

密码加密 bcrypt

  1. 哈希加密(单向加密类似MD5,不可逆)是单程加密方式:1234 => abcd
  2. 在加密的密码中加入随机字符串可以增加密码被破解的难度。
  3. 使用:

     // 导入bcrypt模块
     const bcrypt = require('bcrypt');
     // 生成随机字符串 gen => generate 生成 salt 盐
     let salt = await bcrypt.genSalt(10);
     // 使用随机字符串对密码进行加密
     let pass = await bcrypt.hash('明文密码', salt);
        
     // 密码比对
     let isEqual = await bcrypt.compare('明文密码', '加密密码');
    
  4. bcrypt依赖的其他环境
    1. python 2.x (mac系统默认已经安装,不需要安装。可以通过:python --version 命令查看)
    2. node-gyp(直接全局安装)
      1. npm install -g node-gyp
    3. windows-build-tools (windows下才需要安装)
      1. npm install --global --production windows-build-tools
    4. 安装bcrypt: npm install bcrypt

1.cookie

  1. cookie:浏览器在电脑硬盘中开辟的一块空间,主要供服务器端存储数据。
    1. cookie中的数据是以域名的形式进行区分的。
    2. cookie中的数据是有过期时间的,超过时间数据会被浏览器自动删除。
    3. cookie中的数据会随着请求被自动发送到服务器端。
      1. F12->Network->点击一个请求,可以看到请求头(Request Headers)中有一个Cookie字段存储的数据。
      2. 当客户端发送请求时,Cookie会随着请求头一起发送到服务端
  2. 客户端的js服务器端都可以向cookie中存储数据,但是主要是用于服务端存储数据的
  3. 如何查看一个网站的cookie存储数据
    1. F12->Application->Cookies
  4. cookie的作用就是服务器端向客户端存放一些临时数据
  5. Cookie缓存的流程:当客户端第一次访问服务器,服务器在做出响应的同时将一些数据存储在客户端的cookie中;当客户端再一次发送请求访问服务器,客户端就会将cookie通过请求头携带给服务器。

2.session

  1. 实际上就是一个对象,存储在服务器端的内存中,在session对象中也可以存储多条数据,每一条数据都有一 个sessionid做为唯一标识。

3.cookie与session搭配使用

  1. 客户端通过邮件地址、密码参数向服务器发送登录请求
  2. 服务端进行参数验证,验证过后,服务端将用户的信息存储到session对象中,生成一个sessionid,并将这个sessionid响应给客户端,并存储到客户端的cookie中。
  3. 当客户端下一次访问服务器时,cookie会自动发送给服务端,服务器端拿到cookie中存储的sessionid,在服务端的session对象中查找相应的信息,找到就证明已登录,反之未登录

4.在node.js中需要借助express-session实现session功能。

  1. 引入express-session,即该中间件是express官方提供,是express中间件函数
     const session = require('express-session'); 
    
  2. 给请求配置session

     app.use(session({ secret: 'secret key' }));
    
    1. 使用app.use()中间件拦截所有的请求,并将请求全部交给session对象处理
    2. session({secret: 'secret key' }) 方法的作用:
      1. 创建一个session对象,然后将这个session对象赋值给请求对象req作为属性
      2. session对象可以用来在服务端保存用户的信息,然后生成一个数据的唯一标识sessionid
      3. 将sessionid存储到客户端的cookie中
      4. 当客户端再次访问服务端时,方法会达到客户端传递过来的cookie,拿到sessionid,在session对象中查到相应的数据
    3. session方法的参数:{secret: 'secret key'}
      1. 该参数是一个对象,第一个成员为secret,秘钥
      2. 作用是用来加密:向session中存储的用户信息以及向客户端cookie中存储的sessionid
      3. 该秘钥客户端看不到,加解密全部在服务端,因此具备安全性。
  3. 代码举例:

     const session = require('express-session');
     // 配置session
     // 配置session
     app.use(session({
         secret:'secret key',    //加密秘钥
         saveUninitialized:false, //默认不初始化cookie
         cookie:{
             maxAge: 24 * 60 * 60 * 1000 //设置cookie失效时间为1天
         }
     }))
     //客户端的登录请求
     admin.post('/login',async (req,res)=>{
         ...
         // 登录成功,将用户名存储在请求对象中
         // 向session对象中存储数据,session会自动生成一个sessionid,然后自动将sessionid存储到客户端的cookie中
         req.session.username = '客户端发送过来的用户名';
         // res.send('登录成功!');
         // express框架的 重定向,跳转到用户列表页面
         res.redirect('/admin/user');
    
         // 原生node的重定向
         // res.writeHead(301, {
         //     Location: '/admin/user'
         // });
         // res.end();
                
     });
        
     //服务端查看session中的存储数据,该方法内部会自动获取用户端传递过来的cookie,获取sessionid,然后查出数据
     let username = req.session.username;
        
     //删除session、删除cookie
     req.session.destroy(function () {
         // 删除cookie,connect.sid为session组件默认的cookie的name
         res.clearCookie('connect.sid');
         // 重定向到用户登录页面
         res.redirect('/admin/login');
     });
    

服务端的重定向

  1. 重定向:即当满足一定条件后,跳转到相应的页面
  2. Node原生服务器代码的重定向方法:

     // 原生node的重定向
     // res.writeHead(301, {
     //     Location: '/admin/user'
     // });
     // res.end();
    
  3. 使用express框架搭建服务代码的重定向方法

     // express框架的 重定向,跳转到用户列表页面
     res.redirect('/admin/user');
    

表单字段验证第三方组件Joi

  1. 当一个表单(form)有很多的字段时,而且我们需要对每个字段格式进行验证,比较麻烦,此时就可以借助第三方插件Joi
  2. Joi: JavaScript对象的规则描述语言和验证器。
    1. 在组件内部定义了许多验证规则,并提供语法将不同的规则组合起来,最终形成符合要求的规则
    2. 然后通过组合的规则验证目标对象
  3. 代码示例:

     //引用组件
     const Joi = require('joi'); 
     //定义规则
     const schema = {
         //string():必须是字符串 alphanum:字母、数字类型的 min:最小3个字节 max最大30 required: 不能为空(默认可以没有该字段)
         username: Joi.string().alphanum().min(3).max(30).required().error(new Error(‘错误信息’)), 
         //regex:使用正则规则
         password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
         //[]一个数组,内部既可以是字符串,也可以是数字
         access_token: [Joi.string(), Joi.number()],
         // Joi.number:数字 integer:整数
         birthyear: Joi.number().integer().min(1900).max(2013),
         //Joi.string:字符串,email:邮件格式
         email: Joi.string().email() 
     };
     //验证
     Joi.validate({username: 'abc', birthyear: 1994 }, schema);
    

JS读取文件并显示图片FileReader

  1. FileReader为JS的内置构造函数
  2. 读取图片文件:

     var reader = new FileReader(); 
     reader.readAsDataURL('文件'); 
     reader.onload = function () {
         console.log(reader.result); 
     }
    
  3. 案例:选择一张图片,然后预览显示:

     <!-- multiple: 允许用户选择多个文件-->
     <!-- <input type="file" name="cover" id="file" multiple>-->
     <input type="file" name="cover" id="file">
     <div class="thumbnail-waper">
         <img class="img-thumbnail" src="" id="preview">
     </div>
        
     //js部分
     // 文件上传控件
     var file = document.querySelector('#file');
     //img标签
     var preview = document.querySelector('#preview');
     // 选择完文件
     file.onchange = function(){
         // 1. 创建文件读取对象
         var reader = new FileReader();
         // 2. 读取文件
         // this.files 用户选择的文件列表
         reader.readAsDataURL(this.files[0]); 
         reader.onload = function () {
             //为base64位图片数据
             console.log(reader.result); 
             // 将文件读取结果显示在img中
             preview.src = reader.result;
         }
     }
    

数据分页 mongoose-sex-page

  1. 作用:改第三方组件是专门用来做数据分页功能
  2. 使用方式

     const pagination = require('mongoose-sex-page'); 
     //page:当前第几页 size:每页显示多少数据 display:客户端要显示的页码 exec:向数据库发送查询请求
     pagination(集合构造函数).page(1) .size(20) .display(8) .exec();
    
  3. 返回结果

     {
         "page":1,//当前页
         "size": 2,//每页显示数据条数
         "total":8, //总共的数据条数
         "records":[
             //查询出来的具体数据
             {
                 "id":"33333",
                 "title":"测试文字"
             }
         ],
         "pages":4,//总共的页数
         "display":[1,2,3,4] //客户端显示的页码
     }
    

开发环境与生产环境

  1. 什么是开发环境与生产环境
    1. 环境,就是指项目运行的地方,当项目处于开发阶段,项目运行在开发人员的电脑上,项目所处的环境就是开发环境。当项目开发完成以后,要将项目放到真实的网站服务器电脑中运行,项目所处的环境就是生产环境。
  2. 为什么要区分开发环境与生产环境
    1. 因为在不同的环境中,项目的配置是不一样的,需要在项目代码中判断当前项目运行的环境,根据不同的环境应用不同的项目配置。
    2. 开发环境连接的数据库是开发者在自己电脑上搭建的数据库,生产环境连接的数据库是生产环境的数据库,数据库的连接地址、账号密码都不一样
  3. 如何区分开发环境与生产环境
    1. 通过设置电脑操作系统中的系统环境变量区分当前是开发环境还是生产环境。
    2. 步骤:
      1. 设置当前电脑的系统环境变量(变量名:NODE_ENV 值:development)、生产环境电脑的系统环境变量(变量名:NODE_ENV 值:product)(百度)
      2. 重新启动项目的命令行工具
      3. 项目代码中获取当前系统环境变量加以区分

         if (process.env.NODE_ENV == 'development') {
              // 开发环境
          } else {
              // 生产环境
          }
        

第三方模块config

  1. 作用:允许开发人员将不同运行环境下的应用配置信息抽离到单独的文件中,模块内部自动判断当前应用的运行环境,并读取对应的配置信息,极大提供应用配置信息的维护成本,避免了当运行环境重复的多次切换时,手动到项目代码中修改配置信息
  2. 使用步骤
    1. 使用npm install config命令下载模块
    2. 在项目的根目录下新建config文件夹
    3. config文件夹下面新建default.json、development.json、production.json文件:默认环境配置信息、开发环境配置信息、生产环境配置信息
      1. 模块内部会判断当前环境(通过上面设置的系统环境变量值判断),读取相应的json配置文件,当要读取的都没有找到时到default.json中查找
    4. 在项目中通过require方法,将模块进行导入
    5. 使用模块内部提供的get方法获取配置信息

       console.log(config.get('title'));
      
  3. 将敏感配置信息存储在环境变量中
    1. 在config文件夹中建立custom-environment-variables.json文件
    2. 配置项属性的值填写系统环境变量的名字
    3. 项目运行时config模块查找系统环境变量,并读取其值作为当前配置项属于的值

express的中间件margan

  1. 如果需要监听客户端发送到后台的所有请求,则需要用express的中间件morgan来打印到控制台中,安装中间件npm install margon

     if (process.env.NODE_ENV == 'development') {
         // 开发环境
         // 在开发环境中,监听客户端发送到服务器的所有请求,并打印到终端
         app.use(morgan('dev'));
     } else {
         // 生产环境
     }
    
Table of Contents