密码加密
- 使用
bcryptjs对用户密码进行加密 - 加密之后的密码,无法被逆向破解
- 同一铭文密码多次加密,得到的加密结果各不相同,保证了安全性
安装
npm install bcryptjs
使用
const bcrypt = require('bcryptjs')
// 再注册用户的处理函数中,确认用户名可用后,调用bcrypt.hashSync(明文密码,随机盐长度)方法,对用户的密码进行加密处理
// 对用户的密码,进行bcryptjs加密,返回值是加密之后的字符串
userinfo.password = bcrypt.hashSync(userinfo.password, 10)
表单数据验证
- 使用
@hapi/joi包,为表单中携带的每个数据项,定义验证规则
npm install @hapi/joi
- 安装
@escook/express-joi中间件,来实现自动对表单数据进行验证的功能
npm install @escook/express-joi
- 定义信息验证规则
const joi = require('@hapi/joi')
/**
* string() 值必须是字符串
* alphanum() 值只能是包含 a-zA-Z0-9 的字符串
* min(length) 最小长度
* max(length) 最大长度
* required() 值是必填项,不能为 undefined
* pattern(正则表达式) 值必须符合正则表达式的规则
*/
// 用户名验证规则
const username = joi.string().alphanum().min(1).max(10).required()
const password = joi.string().pattern(/^[\S]{6,12}$/).required()
// 定义 标题、分类Id、内容、发布状态 的验证规则
const title = joi.string().required()
const cate_id = joi.number().integer().min(1).required()
const content = joi.string().required().allow('')
const state = joi.string().valid('已发布', '草稿').required()
// 导出注册和登录表单验证规则对象
exports.reg_login_schema = {
body:{
username,
password
}
}
---------------------------------
// 在路由文件中导入验证规则
const expressJoi = require('@escook/express-joi')
const { reg_login_schema } = require('../schema/user')
router.post('/reguser', exoressJoi(reg_login_schema), userHandler.regUser)
- 在
app.js的全局错误中间件中,捕获验证失败的错误,并把验证失败的结果响应给客户端
const joi = require('@hapi/joi')
app.use(function(err, req, res, next){
// 数据验证失败
if(err instanceof joi.ValidationError) return res.cc(err)
// 位置错误
res.cc(err)
})
登录(jwt)
- 判断用户输入的密码是否正确,调用
bcrypt.compareSync(用户提交的密码,数据库中的密码)方法比较密码是否一致
const compareResult = bcrypt.compareSync(userinfo.password, results[0].password)
// 如果对比的结果等于false,则证明用户输入的密码错误
if(!compareResult){
return res.cc('登陆失败')
}
- 剔除密码和头像的值
const user = { ...results[0], password:'', user_pic:'' }
- 安装生成token字符串的包
npm install jsonwebtoken
- 导入jsonwebtoken包
const jwt = require('jsonwebtoken')
- 在config.js中向外狗狗想加密和还原token的
jwtScretKey字符串
module.exports = {
jwtSecretKey: 'Lzt **^_^**'
}
- 将用户信息加密成token字符串
const config = require('../config')
const tokenStr = jwt.sign(user, config.jwtSecretKey, { expiresIn: '10h' })
- 将生成的token字符串响应给客户端
res.send({
status: 0,
message: '登录成功',
token: 'Bearer ' + tokenStr
})
- 在
app.js中注册路由之前,配置解析token的中间件
npm install express-jwt
const config = require('../config')
// 解析 token 中间件
const expressJWT = require('express-jwt')
// 使用.unless({path:[/^\/api\//]})指定哪些接口不需要进行token认证
app.use(expressJWT({ secret: config.jwtSecretKey })).unless({path:[/^\/pai\//]})
// 在错误级别中间件中,捕获并处理Token认证失败后的错误
app.use(function(err, req, res, next){
// 捕获身份认证失败的错误
if(err.name === 'UnauthorizedError') return res.cc('身份认证失败')
})
multer解析表单数据
注意:使用express.urlencoded()中间件无法解析multipart/form-data格式的请求数据
npm install multer
- 在路由模块中配置 multer
const multer = require('multer')
const path = require('path')
const upload = multer({ dest: path.join(__dirname, '../uploads') })
- 修改路由
// 发布新文章的路由
// upload.single()是一个局部生效的中间件,用来解析FormData格式的表单数据
// 将文件类型的数据,解析并挂在到req.file属性中
// 将文本类型的胡数据,解析并挂在到req.body属性中
router.post('/add', upload.single('cover_img'), article_handler.addArticle)
------
exports.addArticle = (req, res)=>{
console.log(req.body)
console.log(req.file)
res.send('ok')
}
// 发布新文章的处理函数
exports.addArticle = (req, res) => {
// 手动判断是否上传了文章封面
if (!req.file || req.file.fieldname !== 'cover_img') return res.cc('文章封面是必选参数!')
// TODO:表单数据合法,继续后面的处理流程...
})
361

被折叠的 条评论
为什么被折叠?



