express+mongoose数据库入库密码进行加密与验证
第一步: 创建项目
使用express自动构建工具创建一个测试项目
express test
进入项目目录安装一下依赖
安装mongoose模块
npm i mongoose
重点: 安装bcryptjs模块
bcryptjs模块是一个nodejs的一个字符串加盐(slat)加密模块, 普通的md5加密虽然是不可逆的,
但是md5可以使用字典攻击来获取加密信息, 所以就需要在原有的信息上加盐(slat), 盐本质是也是一串字符串,
将需要加密的信息和盐进行拼接, 再进行md5加密, 可以防止字典攻击, 不过这些操作不需要我们来实现,
bcryptjs模块已经帮我们实现了, 我们只需要使用其中的几个方法。
使用npm i bcryptjs安装bcryptjs模块。
npm i bcryptjs
第二步: 编写model对象和接口
在项目根目录下创建models.js文件, 位置不重要可以随便创建。
编写models模块
代码如下
const mongoose = require('mongoose')
const bcryptjs = require('bcryptjs')
// 连接数据库
mongoose.connect('mongodb://127.0.0.1/bcrypt', err => {
if (!err) {
console.log('数据库连接成功');
}
})
// 定义schema
const userSchema = mongoose.Schema({
username: String,
password: {
type: String,
set(val) { // 每次对数据库进行修改或插入时都会执行set
return bcryptjs.hashSync(val) // 对入库的密码进行加密
}
}
})
// 定义model
const userModel = mongoose.model('user', userSchema)
// 暴露model
module.exports = {
userModel
}
在app.js文件中编写注册登录接口
代码如下
var { userModel } = require('./models') // 引入userModel
var bcryptjs = require('bcryptjs') // 引入bcryptjs模块
app.post('/register', async (req, res) => {
// 假设已经对数据进行过验证, 因为在model中定义了set方法所以这里直接入库
await userModel.create(req.body)
res.send('ok')
})
app.post('/login', async (req, res) => {
let username = req.body.username
let password = req.body.password
let user = await userModel.findOne({ username })
if (!user) {
return res.send('没有这个用户!')
}
// 使用bcryptjs.compareSync方法进行验证,第一个参数是要验证的字符串,第二个参数是加密过的字符串
if (!bcryptjs.compareSync(password, user.password)) {
return res.send('密码错误!')
}
res.send('登录成功!')
})
第三步: 测试效果
输入nodemon启动项目
用postman测试注册接口
可以看到密码已经加密了
测试登录接口
可以看到登录接口也没有问题
总结
主要用到了bcryptjs模块中的两个方法: bcryptjs.hashSync(val) 生成加密字符串
bcryptjs.compareSync(val, hasval) 验证参数二是否是由参数一加密而来的
如果想了解这个两个方法原理的话可以百度一下
在定义Schema对象时可以修改字段对象的set()方法