(黑马程序员)MongoDB + Express + art-template 项目实例-博客管理系统 第三页

2、项目功能实现

2.1 登录与退出功能

2.1.1、创建用户集合,初始化用户

1)连接数据库

在 model 目录下新建 connect.js 文件:

// 引入 mongoose 第三方模块
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost/blog', { useNewUrlParser: true, useUnifiedTopology: true}).then(() => console.log('数据库连接成功')).catch(() => console.log('数据库连接失败'))

在 app.js 文件中引用:

// 数据库连接
require('./model/connect');

在命令行工具中可以看到:

2)创建用户集合

在 model 目录下新建 user.js:

// 引入 mongoose 第三方模块
const mongoose = require('mongoose');
// 创建用户集合规则
const userSchema = new mongoose.Schema({username: {type: String,required: true,minlength: 2,maxlength: 20},email:{type: String,required: true,//  唯一性,保证邮箱地址在插入数据库时不重复unique: true},password: {type: String,required: true},// admin-超级管理员 normal-普通用户 role: {type: String,required: true},// 0:启用状态  1:禁用状态state: {type: Number,default: 0}
});
// 创建用户信息集合
const User = mongoose.model('User', userSchema);// 将用户信息集合作为模块成员进行导出
module.exports = {User
}

3)初始化用户

在 user.js 文件中创建测试用户:

// 引入 mongoose 第三方模块
const mongoose = require('mongoose');
// 创建用户集合规则
const userSchema = new mongoose.Schema({username: {type: String,required: true,minlength: 2,maxlength: 20},email:{type: String,required: true,//  唯一性,保证邮箱地址在插入数据库时不重复unique: true},password: {type: String,required: true},// admin-超级管理员 normal-普通用户 role: {type: String,required: true},// 0:启用状态  1:禁用状态state: {type: Number,default: 0}
});
// 创建用户信息集合
const User = mongoose.model('User', userSchema);User.create({username: 'itjoe',email: 'joe@163.com',password: '123456',role: 'admin',state: 0
}).then(() => {console.log('用户创建成功')
}).catch(() => {console.log('用户创建失败')
})// 将用户信息集合作为模块成员进行导出
module.exports = {User
}

在 app.js 文件中引用:

// 用户集合
require('./model/user');

这时在命令行工具中可以看到:用户创建成功

 打开 Compass 软件,可以看到 blog 数据库中有一个 users 集合:创建用户成功

然后把 app.js 中引入 user.js 的代码删除,并把 user.js 中创建用户部分的代码注释掉。

2.1.2、 为登录表单项设置请求地址、请求方式以及表单项name属性 

打开 login.art 文件,添加代码: 

2.1.3.、当用户点击登录按钮时,客户端验证用户是否填写了登录表单

给表单添加 id:

在页面下方添加表单的点击事件代码:

打开浏览器刷新页面,随便输入一些内容,可以看到控制台打印出的数组:刚输入的内容

继续修改代码:

回到浏览器刷新页面,重新输入内容,可以看到控制台打印出的对象:

在一个真实项目中,对表单进行处理是很常见的操作,所以我们可以把这个方法变为公共的方法。

在 public - admin - js 目录下,新建 common.js 文件,把 serializeToJson 方法剪切过来:

function serializeToJson(form) {var result = {};// serializeArray() 获取到表单中用户输入的内容,返回值是数组 // [{name: 'email', value:: '用户输入的内容'}]var f = form.serializeArray();// 把数组转换为对象 {enail: 'zhangsan@163.com', password: '123456'}f.forEach(function(item) {result[item.name] = item.value;});return result;
}

 再在 login.art 文件中引入 common.js 文件:

刷新浏览器冲洗验证下方法是否可以正常使用。

我们还可以再骨架文件中引入 common.js 文件,打开 layout.art 文件:


{{block 'link'}} {{/block}}
{{block 'main'}} {{/block}}{{block 'script'}} {{/block}}

2.1.4.、如果其中一项没有输入,阻止表单提交

继续修改 login.art 文件中的 js 代码:

浏览器刷新页面,不输入内容就提交的话,会弹出提示信息。

2.1.5、 服务器端接收请求参数,验证用户是否填写了登录表单

把表单的请求地址改为:/admin/login

Express 中接收 post 请求参数需要借助第三方包 body-parser

在命令行工具中下载安装:

npm install body-parser

打开 app.js 文件,引入 body-parser 模块,并进行全局的配置:

// 引入 body-parser 模块,用来处理 post 请求参数
const bodyParser = require('body-parser');// 配置 body-parser 模块,处理 post 请求参数
app.use(bodyParser.urlencoded({ extended: false }));

extended: false 方法内部使用 querystring 模块处理请求参数的格式

extended: true 方法内部使用第三方模块 qs 处理请求参数的格式

然后重启启动服务器:nodemon app.js

打开 admin.js 文件,添加 /login 的 post 请求:

// 实现登录功能
admin.post('/login', (req, res) => {// 接收请求参数res.send(req.body);
});
// 先把请求参数显示到页面中看下效果

下面要对请求参数进行二次验证

2.1.6、 如果其中一项没有输入,为客户端做出响应,阻止程序向下执行

继续编辑下 admin.js 的代码:

// 实现登录功能
admin.post('/login', (req, res) => {// 接收请求参数const {email, password} = req.body;// 如果用户没有输入邮件地址或密码if (email.trim().length == 0 || password.trim().length == 0) {return res.status(400).send('

邮件地址或密码错误

')} });

我们测试下,先把 login.art 文件下面的 js 代码注释掉,然后刷新浏览器,不填写信息直接提交,可以看到:服务器端的验证

可以把页面美化下,在 views 目录下新建 error.art 文件:

{{extend './common/layout.art'}}{{block 'main'}}

{{msg}}

{{/block}}

然后修改下 admin.js 文件中的代码:

// 实现登录功能
admin.post('/login', (req, res) => {// 接收请求参数const {email, password} = req.body;// 如果用户没有输入邮件地址或密码if (email.trim().length == 0 || password.trim().length == 0) {// return res.status(400).send('

邮件地址或密码错误

')return res.status(400).render('admin/error.art', {msg: '邮件地址或密码错误'})}});

刷新页面,重新提交下看效果。

下面我们在 error.art 文件中设置定时器,3秒后再跳回到 login 登陆页:

{{extend './common/layout.art'}}{{block 'main'}}

{{msg}}

{{/block}}{{block 'script'}} {{/block}}

回到浏览器中刷新,OK,3秒后跳回到 login 登陆页了。

下面要根据客户端传递过来的邮箱地址,查询用户是否存在。如果用户不存在,则阻止程序继续向下执行,并为客户端做出响应,告知客户端邮箱地址或者密码错误;如果用户存在,则使用客户端传递过来的密码和从数据库中查询出来的用户信息中的密码,进行比对。若两者的密码一致,则表示登录成功;若不一致,则表示登录失败。

2.1.7、根据邮箱地址查询用户信息

继续编辑 admin.js 文件的登录功能代码:

// 导入用户集合构造函数
const { User } = require('../model/user');// 实现登录功能
admin.post('/login', async (req, res) => {。。。// 根据邮箱地址查询用户信息let user = await User.findOne({email: email.trim()})
});

2.1.8、如果用户不存在,为客户端做出响应,阻止程序向下执行

继续编辑 admin.js 文件的登录功能代码:

// 实现登录功能
admin.post('/login', async (req, res) => {。。。// 根据邮箱地址查询用户信息let user = await User.findOne({email: email.trim()})// 如果没有查询到用户,user 变量为空if (user != null) {// 查询到了用户} else {// 没有查询到用户res.status(400).render('admin/error.art', {msg: '邮件地址或密码错误'})} 
});

2.1.9、如果用户存在,将用户名和密码进行比对

继续编辑 admin.js 文件的登录功能代码:

// 实现登录功能
admin.post('/login', async (req, res) => {。。。// 根据邮箱地址查询用户信息let user = await User.findOne({email: email.trim()})// 如果没有查询到用户,user 变量为空if (user != null) {// 查询到了用户,将客户端传递过来的密码与查询出用户信息中的密码进行比对if (password == user.password) {}else{}} else {// 没有查询到用户res.status(400).render('admin/error.art', {msg: '邮件地址或密码错误'})} 
});

2.1.10、比对成功,用户登录成功

// 查询到了用户,将客户端传递过来的密码与查询出用户信息中的密码进行比对if (password == user.password) {//登录成功res.send('登录成功');}else{// 登录失败}

2.1.11、比对失败,用户登录失败

// 查询到了用户,将客户端传递过来的密码与查询出用户信息中的密码进行比对if (password == user.password) {//登录成功res.send('登录成功');}else{// 登录失败res.status(400).render('admin/error.art', {msg: '邮件地址或密码错误'})}

刷新浏览器,输入正确的邮件和密码,可以看到:


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部