案例功能完善
更新时间: 2024-11-18 09:12:55
# 结合API接口
- 新建 /router/api/account.js,内容和/router/index.js一致
- 在app.js中应用 account.js
// 导入 account 接口路由文件
const accountRouter = require('./routes/api/account')
//...
//...
app.use('/api',accountRouter)
//...
1
2
3
4
5
6
2
3
4
5
6
# 获取账单接口
// 记账本的列表
router.get('/account', function(req, res, next) {
// 获取所有的账单信息
AccountModel.find().sort({time: -1}).then(data => {
res.json({
// 响应编号
code: '0000',
// 响应的信息
msg: '读取成功',
// 响应的数据
data: data
})
}).catch(err => {
res.json({
code: '1001',
msg: '读取失败',
data: null
})
})
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建账单接口
// 新增记录
router.post('/account', (req, res) => {
AccountModel.create({
...req.body,
time: moment(req.body.time).toDate()
}).then(data => {
res.json({
// 响应编号
code: '0000',
// 响应的信息
msg: '创建成功',
// 响应的数据
data: data
})
}).catch(err => {
res.json({
code: '1002',
msg: '创建失败',
data: null
})
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 删除账单接口
// 删除记录
router.delete("/account/:id", (req, res) => {
// 获取params的id参数
let id = req.params.id
// 删除
AccountModel.deleteOne({_id: id}).then(data => {
res.json({
code: '0000',
mgs: '删除成功',
data: null
})
}).catch(err => {
res.json({
code: '1003',
msg: '删除失败'
})
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 获取单条账单接口
// 获取单个账单信息
router.get('/account/:id',(req, res) => {
// 获取 id 参数
let {id} = req.params
// 查询数据库
AccountModel.findById(id).then(data => {
res.json({
code: '0000',
msg: '读取成功',
data: data
})
}).catch(err => {
res.json({
code: '1004',
mgs: '读取失败',
data: null
})
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 更新账单接口
router.patch('/account/:id',(req, res) => {
// 获取id参数值
let {id} = req.params
// 更新数据库
AccountModel.updateOne({_id:id}, req.body).then(data => {
// 再次查询数据库,获取单条数据
AccountModel.findById(id).then(data1 => {
res.json({
code: '0000',
msg: '更新成功',
data: data1
})
}).catch(err => {
res.json({
code: '1004',
msg: '读取失败',
data: null
})
})
}).catch(err => {
console.log(err)
res.json({
code:'1005',
mgs:'更新失败',
data: null
})
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 响应注册页面
- 新建 views/auth/reg.ejs 模板
- 新建 /routes/web/auth.js
var express = require('express')
var router = express.Router()
// 注册
router.get('/reg', (req, res) => {
// 响应HTML内容
res.render('auth/reg')
})
module.exports = router
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- 在app.js中引入auth.js并注册
//...
const authRouter = require('./routes/web/auth')
var app = express();
app.use('/', authRouter);
//...
module.exports = app;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 注册用户
- 新建用户模型对象 models/UserModel.js
// 导入 mongoose
const mongoose = require('mongoose')
// 创建文档的结构对象
// 设置集合中文档的属性以及属性值的类型
let UserSchema = new mongoose.Schema({
username: String,
password: String
})
// 创建模型对象,对文档操作的封装对象
let UserModel = mongoose.model('users', UserSchema)
// 暴露模型对象
module.exports = UserModel
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- 安装md5依赖 npm i md5
- 新增注册接口
// 导入用户的模型
const UserModel = require('../../models/UserModel')
const md5 = require('md5')
//....
// 注册用户
router.post('/reg', (req, res) => {
UserModel.create({...req.body, password: md5(req.body.password)}).then(data => {
console.log(data)
res.render('success', {msg:'注册成功', url:'/login'})
}).catch(err => {
res.status(500).send('注册失败,请稍后再试')
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 修改模版
<form method="post" action="/reg">
<div class="form-group">
<label for="item">用户名</label>
<input name="username" type="text" class="form-control" id="item" />
</div>
<div class="form-group">
<label for="time">密码</label>
<input name="password" type="password" class="form-control" id="time" />
</div>
<hr>
<button type="submit" class="btn btn-primary btn-block">注册</button>
</form>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 用户登录
- 用户登录接口
// 登录路由
router.get('/login',(req, res) => {
res.render('auth/login')
})
// 登录
router.post('/login',(req, res) => {
// 获取用户名和密码
let {username, password} = req.body
// 查询数据库
UserModel.findOne({username: username, password: md5(password)}).then(data => {
console.log(data)
if(!data) {
res.send("账号密码错误")
}else{
res.render('success', {msg:'登录成功', url: '/account'})
}
}).catch(err => {
res.status(500).send('登录失败')
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- 新建登录模版
# 写入session
- 在app.js里配置session中间件
// app.js
// 导入 express-session
const session = require('express-session')
const MongoStore = require('connect-mongo')
// 导入配置项
const {DBHOST, DBPORT, DBNAME} = require('./config/config')
var app = express();
// 设置session的中间件
app.use(session({
name:'sid', // 设置cookie的name,默认值是:connct.sid
secret: 'atguigu', // 参与加密的字符串(又称签名) 加盐
saveUninitialized: false, // 是否每次请求都设置一个cookie来存储session
resave: true, // 是否在每次请求时重新保存session
store: MongoStore.create({
mongoUrl: `mongodb://${DBHOST}:${DBPORT}/${DBNAME}`
}),
cookie: {
httpOnly: true, // 开启后前端无法通过js操作cookie
maxAge: 1000 * 60 * 20 // 这一条是控制 sessionID 的过期时间的
}
}))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- 登录接口中保存session
// 登录
router.post('/login',(req, res) => {
// 获取用户名和密码
let {username, password} = req.body
// 查询数据库
UserModel.findOne({username: username, password: md5(password)}).then(data => {
console.log(data)
if(!data) {
res.send("账号密码错误")
}else{
// 写入session
req.session.username = data.username
req.session._id = data._id
res.render('success', {msg:'登录成功', url: '/account'})
}
}).catch(err => {
res.status(500).send('登录失败')
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 用户登录检测
- 检测登录中间件
// middlewares/checkLoginMiddleware.js
// 声明中间件检测登录
let checkLoginMiddleware = (req, res, next) => {
// 判断
if(!req.session.username) {
return res.redirect('login')
}
next()
}
module.exports = checkLoginMiddleware
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 使用中间件
//...
// 导入中间件检测登录
let checkLoginMiddleware = require('../../middlewares/checkLoginMiddleware')
// 记账本的列表
router.get('/account', checkLoginMiddleware, function(req, res, next) {
// 获取所有的账单信息
AccountModel.find().sort({time: -1}).then(data => {
res.render('list',{accounts: data, moment: moment})
})
});
// 添加记录
router.get('/account/create',checkLoginMiddleware,function(req, res, next) {
res.render('create')
})
// 新增记录
router.post('/account',checkLoginMiddleware, (req, res) => {
AccountModel.create({
...req.body,
time: moment(req.body.time).toDate()
}).then(data => {
res.render('success', {msg: '添加成功哦~', url:'/account'})
}).catch(err => {
console.log(err)
res.status(500).send('插入失败~')
return
})
})
// 删除记录
router.get("/account/:id",checkLoginMiddleware, (req, res) => {
// 获取params的id参数
let id = req.params.id
// 删除
AccountModel.deleteOne({_id: id}).then(data => {
// 提醒
res.render('success', {msg: '删除成功~', url:'/account'})
}).catch(err => {
res.status(500).send('删除失败~~')
})
})
module.exports = router;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 退出登录
- 修改模板,在列表模板上加上退出按钮
<div class="row text-right">
<div class="col-xs-12" style="padding-top:20px;">
<a href="/logout" class="btn btn-danger">退出</a>
</div>
</div>
1
2
3
4
5
2
3
4
5
- 退出接口
// 退出登录
router.get('/logout',(req, res) => {
// 销毁session
req.session.destroy(() => {
res.render('success', {msg: '退出成功', url: '/login'})
})
})
1
2
3
4
5
6
7
2
3
4
5
6
7
# 首页和404页面
- 首页路由规则
// 添加首页路由规则
router.get('/',(req, res) => {
res.redirect('/account')
})
1
2
3
4
2
3
4
- 新建404页面模板
- app.js中应用404页面
// catch 404 and forward to error handler
app.use(function(req, res, next) {
// 响应 404
res.render('404')
});
1
2
3
4
5
2
3
4
5
# 登录响应token
- 修改登录接口
// router/api/auth.js
// 登录
router.post('/login',(req, res) => {
// 获取用户名和密码
let {username, password} = req.body
// 查询数据库
UserModel.findOne({username: username, password: md5(password)}).then(data => {
console.log(data)
if(!data) {
res.json({
code: '2002',
msg: '用户名或密码错误',
data: null
})
}else{
// 创建当前用户的token
let token = jwt.sign({
username: data.username,
_id: data._id
},'atguigu',{
expiresIn: 60 * 20
})
// 响应token
res.json({
code: '0000',
msg: '登录成功',
data: token
})
}
}).catch(err => {
res.json({
code: '2001',
msg: '数据库读取失败',
data: null
})
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
- 在app.js中去注册
const authApiRouter = require('./routes/api/auth')
app.use('/api',authApiRouter)
1
2
2
# token校验
- token校验中间件
// middleware/checkTokenMiddleware.js
const jwt = require('jsonwebtoken')
const checkTokenMiddleware = (req, res, next) => {
// 获取 token
let token = req.get('token')
if(!token) {
return res.json({
code: '2003',
msg: 'token缺失',
data: null
})
}
// 校验 token
jwt.verify(token, 'atguigu', (err, data) => {
// 检测 token 是否正确
if(err) {
return res.json({
code: '2004',
msg: 'token校验失败',
data: null
})
}
// 如果token校验成功
next()
})
}
module.exports = checkTokenMiddleware
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
- 使用中间件
//...
// 校验token中间件
const checkTokenMiddleware = require("../../middlewares/checkTokenMiddleware")
// 记账本的列表
router.get('/account', checkTokenMiddleware, function(req, res, next) {
//...
});
// 新增记录
router.post('/account', checkTokenMiddleware, (req, res) => {
//...
})
// 删除记录
router.delete("/account/:id",checkTokenMiddleware, (req, res) => {
//...
})
// 获取单个账单信息
router.get('/account/:id',checkTokenMiddleware,(req, res) => {
//..
})
// 更新单个账单信息
router.patch('/account/:id',checkTokenMiddleware,(req, res) => {
//...
})
module.exports = router;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# token功能完善
const jwt = require('jsonwebtoken')
const {secret} = require('../config/config')
const checkTokenMiddleware = (req, res, next) => {
// 获取 token
let token = req.get('token')
if(!token) {
return res.json({
code: '2003',
msg: 'token缺失',
data: null
})
}
// 校验 token
jwt.verify(token, secret, (err, data) => {
// 检测 token 是否正确
if(err) {
return res.json({
code: '2004',
msg: 'token校验失败',
data: null
})
}
// 保存用户的信息
req.user = data
// 如果token校验成功
next()
})
}
module.exports = checkTokenMiddleware
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 本地域名配置
所谓本地域名就是只能在本机使用的域名,一般在开发阶段使用
# 操作流程
编辑文件 C:\Windows\System32\drivers\etc\hosts
127.0.0.1 www.baidu.com
如果修改失败,可以修改该文件的权限
# 原理
在地址栏输入域名之后,浏览器会先进行DNS(Domain Name System)查询,获取该域名对应的IP地址请求会发送到DNS服务器,可以根据域名返回IP地址
可以通过 ipconfig/all 查看本机的DNS服务器
host文件也可以设置域名与IP的映射关系,在发送请求前,可以通过该文件获取域名的IP地址