登录功能
- 用户登录使用邮箱和密码
- 从req.body上解构出邮箱和密码
- 使用User集合以邮箱为查询条件从数据库中查询出对应user
- 如果user不空,说明该用户是注册过的,在数据库中存在
- 判断req.body.password与user.password是否相等
- 相等:登录成功;不相等:登录失败
- 登录成功后express.session可以自动给客户端在cookie中存connect.id
- 下次登录就会携带这个cookie带服务器端进行比对
登录拦截
- 使用app.use中间件
- 判断用户访问的是否是登录页面
const guard = (req, res, next) => {
// 判断用户访问的是否是登录页面
// 判断用户的登录状态
// 如果用户是登录的 将放行
// 如果不是登录的 将重定向到登录页面
if(req.url !== '/login' && !req.session.username) {
//访问的不是登录页面,用户又没有登录,则重定向到
//登录页面
res.redirect('/admin/login');
}else{
// 如果用户未登录且是普通用户
if(req.session.role == 'normal') {
// 重定向到博客首页,阻止程序向下执行
return res.redirect('/home/');
}
next();
}
}
module.exports = guard;
文件上传
- 文件上传必须使用二进制上传
<!--
enctype 指定表单数据的编码类型
application/x-www-form-urlencoded
name=zhangsan&age=20
multipart/form-data 将表单数据编码成二进制类型
-->
-
默认值:application/x-www-form-urlencoded,将表单内容编码成
name=zhangsan&age=20 -
二进制:multipart/form-data,将表单数据编码成二进制类型
-
客户端对表单的操作如下:
// 选择文件上传控件
var file = document.querySelector('#file');
var preview = document.querySelector('#preview');
// 当用户选择完文件以后
file.onchange = function () {
// 1 创建文件读取对象
var reader = new FileReader();
// 用户选择的文件列表
// console.log(this.files[0])
// 2 读取文件
reader.readAsDataURL(this.files[0]);
// 3 监听onload事件
reader.onload = function () {
console.log(reader.result)
// 将文件读取的结果显示在页面中
preview.src = reader.result;
}
}
- 服务器端对文章的存储
module.exports = (req, res) => {
// 1.创建表单解析对象
const form = new formidable.IncomingForm();
// 2.配置上传文件的存放位置
form.uploadsDir = path.join(__dirname, '../', '../', 'public', 'uploads');
// 3.保留上传文件的后缀
form.keepExtensions = true;
// 4.解析表单
form.parse(req, async (err, fields, files) => {
// 1.err错误对象 如果表单解析失败 err里面存储错误信息 如果表单解析成功 err将会是null
// 2.fields 对象类型 保存普通表单数据
// 3.files 对象类型 保存了和上传文件相关的数据
// res.send(files.cover.path.split('public')[1])
await Article.create({
title: fields.title,
author: fields.author,
publishDate: fields.publishDate,
cover: files.cover.path.split('public')[1],
content: fields.content,
});
// 将页面重定向到文章列表页面
res.redirect('/admin/article');
})
// res.send('ok');
}
备注:课程目录
1集:项目简介
2集:项目初始化
npm init -y 初始化生成package.json文件
3.集: 处理静态资源
express.static('静态资源存放目录')
app.use(express.static(path.join(__dirname, 'public')));
7集:登录功能
创建用户集合
10集: 接收post请求,需要用到bodyparser模块
之后是使用req.body就可以接收post请求参数
13集:密码加密
使用bcrypt第三方模块,bcrypt.genSalt()可以生成一个随机字符串
bcrypt.hash(‘明文密码’,随机字符串),返回一个加密后的密码
16集:cookie与session
18集:app.locals 可以存放一些公共的资源
19集:登录拦截
22集:Joi,js对象的规则描述语言和验证器·
24集:对密码加密,使用bcrypt第三方模块
27集:数据分页
31集:用户修改功能
34集:删除用户
34集:文章管理
36集:创建文章集合
38集:文件上传
form表单的enctype的值设置为multipart/form-data,
将欲上传的文件以二进制编码的方式进行上传
服务器端需要使用formidable对文件的二进制编码进行解析
39集:
使用FileReader构造函数创建文件读取对象reader
调用reader下的readAsDataURL方法,传入要上传的文件地址
40集:把文章插入到数据库中
41集:联合查询
Article.find().populate('author');
42集:对日期格式处理,使用dateFormat第三方
43集:文章列表的分页,使用mongoose-sex-page
const pagination = require('mongoose-sex-page');
const articles = await
pagination.(Article).find().page(当前页码)
.size(一页几条数据).display(客户端显示几个页码选项).exec()
45集:为mongodb添加账号
46集:开发环境和生产环境
NODE_EVN development 和 production
50集:第三方模块config,将敏感信息存放到电脑的环境变量中
51集:博客前端展示页面
53集:查询文章内容并展示
54集:字符串的替换
替换内容中的HTML标签
replace(/<[^>]+>/g, '')
57集:文章评论,需要单独创建评论集合
59集:退出状态不显示评论区
60集:评论添加
62集:退出功能(删除cookie中的内容)
req.session.destroy(function() {
res.clearCookie('connect.sid);
});