Node功能型第三方模块

1. 密码加密 bcrypt

  • 哈希加密是单程加密方式:1234 => abcd
  • 在加密的密码中加入随机字符串可以增加密码被破解的难度。
  • 安装 npm install bcrypt
  • bcrypt依赖的其他环境
    1. python 2.x
    1. node-gyp
      npm install -g node-gyp
    1. windows-build-tools
      npm install --global --production windows-build-tools
// 导入bcrypt模块
const bcrypt = require('bcrypt');
// 生成随机字符串 gen => generate 生成 salt 盐
let salt = await bcrypt.genSalt(10);
// 使用随机字符串对密码进行加密
let pass = await bcrypt.hash('明文密码', salt);

2.cookie与session (express-session)

cookie:浏览器在电脑硬盘中开辟的一块空间,主要供服务器端存储数据。

  • cookie中的数据是以域名的形式进行区分的。
  • cookie中的数据是有过期时间的,超过时间数据会被浏览器自动删除。
  • cookie中的数据会随着请求被自动发送到服务器端。
    session:实际上就是一个对象,存储在服务器端的内存中,在session对象中也可以存储多条数据,每一条数据都有一个sessionid做为唯一标识。
  • 在node.js中需要借助express-session实现session功能
  • 安装 npm install express-session
const session = require('express-session');
app.use(session({ secret: 'secret key' }));

//登录成功在session中添加username
//将用户名存储在请求对象中
req.session.username = user.username;
//登录成功可以将user全局开放
req.app.locals.userInfo = user;

//根据session中的username判断登录拦截
(req.url != '/login' && !req.session.username)

3.Joi

  • JavaScript对象的规则描述语言和验证器。
  • 安装 npm install joi
const Joi = require('joi');
const schema = {
    username: Joi.string().alphanum().min(3).max(30).required().error(new Error(‘错误信息’)),
    password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
    access_token: [Joi.string(), Joi.number()],
    birthyear: Joi.number().integer().min(1900).max(2013),
    email: Joi.string().email()
};
Joi.validate({ username: 'abc', birthyear: 1994 }, schema);

示例 user.js

const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
//引入joi模块
const Joi = require('joi');

//创建用户集合
const userSchema = new mongoose.Schema({
        username: {
            type: String,
            required: true,
            minlength: 2,
            maxlength: 20
        },
        email: {
            type: String,
            //保证邮箱地址在插入数据库时不重复
            unique: [true, '邮箱已存在']
        },
        password: {
            type: String,
            required: true
        },
        // admin 超级管理员
        // normal 普通用户
        role: {
            type: String,
            required: true
        },
        // 0 启用状态
        // 1 禁用状态
        statue: {
            type: Number,
            default: 0
        }
    })
;

const User = mongoose.model('User', userSchema);

async function createUser() {
    const salt = await bcrypt.genSalt(10);
    const pass = await bcrypt.hash('123456', salt);
    const user = await User.create({
        username: 'ithedan',
        password: pass,
        email: '358603587@qq.com',
        role: 'admin',
        statue: 0
    });
}

// createUser();
//用户验证信息
const validateUser = (obj) => {
    //定义对象的验证规则
    const schema = {
        username: Joi.string().min(2).max(12).required().error(new Error('用户名不符合要求')),
        email: Joi.string().email().required().error(new Error('邮箱格式不符合要求')),
        password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/).error(new Error('密码格式不符合要求')),
        role: Joi.string().valid('normal', 'admin').required().error(new Error('角色值非法')),
        statue: Joi.number().valid('0', '1').required().error(new Error('状态值非法'))
    };

    //实施验证
    return Joi.validate(obj, schema);
};

//将用户模块作为模块导出
module.exports = {
    User,
    validateUser
};

验证

 try {
        await validateUser(req.body);
    } catch (e) {
        //验证没有通过
        //JSON.stringfy()将对象类型转换成字符串数据类型
        return next(JSON.stringify({path:'***',message:e.message}));
    }

4 .formidable

  • 作用:解析表单,支持get请求参数,post请求参数、文件上传
  • 安装 npm install formidable
 // 引入formidable模块
 const formidable = require('formidable');
 // 创建表单解析对象
 const form = new formidable.IncomingForm();
 // 设置文件上传路径
 form.uploadDir = "/my/dir";
 // 是否保留表单上传文件的扩展名
 form.keepExtensions = false;
 // 对表单进行解析
 form.parse(req, (err, fields, files) => {
     // fields 存储普通请求参数
         // files 存储上传的文件信息
 });

5 .数据分页 mongoose-sex-page

  • 用来处理数据库分页查询的操作
  • 安装 npm install mongoose-sex-page
const pagination = require('mongoose-sex-page');
pagination(集合构造函数).page(1) .size(20) .display(8) .exec();

//查询所有数据(关联查询populate)
    //page指定当前页
    //size 指定每页显示的数据条数
    //display 指定客户端要显示的页面数量
    //exec() 向数据库中发送查询请求
    const articles = await pagination(Article).find({}).page(page).size(2).display(3).populate('author').exec();

//返回数据结构
  {
        "page": 1,
        "size": 2,
        "total": 31,
        "records": [
        {
            "publishDate": "2020-04-01T00:00:00.000Z",
            "cover": "\\uploads\\upload_58395dfb9a86c4247cb27aeca0429945.png",
            "_id": "5ea55868e148fa1930a3f671",
            "title": "测试441",
            "author": {
                "statue": 0,
                "_id": "5ea00b63bdec8411ec0d6f5b",
                "username": "ithedan",
                "password": "$2b$10$dSo.A4giEZZmhp2vdflvWuIvQCKkjrF9w6VNQbE4SM2ihSC8Bglme",
                "email": "358603587@qq.com",
                "role": "admin",
                "__v": 0
            },
            "content": "测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容",
            "__v": 0
        },
        {
            "publishDate": "2020-04-01T00:00:00.000Z",
            "cover": "\\uploads\\upload_811382460ba9fab583151705c3044e99.png",
            "_id": "5ea55898e148fa1930a3f673",
            "title": "测试91",
            "author": {
                "statue": 0,
                "_id": "5ea00b63bdec8411ec0d6f5b",
                "username": "ithedan",
                "password": "$2b$10$dSo.A4giEZZmhp2vdflvWuIvQCKkjrF9w6VNQbE4SM2ihSC8Bglme",
                "email": "358603587@qq.com",
                "role": "admin",
                "__v": 0
            },
            "content": "测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容测试测试内容内容",
            "__v": 0
        }
    ],
        "pages": 16,
        "display": [
        1,
        2,
        3
    ]
    }

6 文件读取 FileReader(图片)

 //当选择文件控件上传对象
    var file = document.querySelector('#file');
    //当用户选择完文件以后
    file.onchange = function () {
        //创建文件读取对象
        var reader = new FileReader();
        //用户选择的的文件列表
        // console.log(this.files[0]);
        //读取文件
        reader.readAsDataURL(this.files[0]);
        //监听onload事件
        reader.onload = function () {
            // console.log(reader.result);
            $('#img-preview').attr('src', reader.result);
        }
    };
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容