介绍 Nodejs 登录与注册并实现与 MongoDB 数据储存与查询
背景
之前一直都有学过 Node,但是没怎么上心,然而现在有业务需求同时也希望自己多掌握点技能,因此下定决心学习 Node。本文内容还是参考《了不起的 Node.js》里面的案例,但只是参考了一部分。
项目例子采用 MVC 模式
项目结构1
2
3
4
5
6
7
8
9
|- view
| |- login.pug
| |- signup.pug
| |- layout.pug
|- model
| |- server.js
|- controller
| |-index.js
|- index.js
所需要的包,其中express-session验证用户信息的。json1
2
3
4
5
6
7
8
9
{
...
"dependencies": {
"express": "^4.16.4",
"body-parser": "^1.19.0",
"express-session": "^1.16.1"
}
...
}
注册
公共模板pug1
2
3
4
5
6
7
8
doctype 5
html
head
title MongoDB example
body
h1 My first MongoDB app
hr
block body
注册界面pug1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//- signup.pug
extends layout
block body
form(action="/signup", method="POST")
fieldset
legend Sign up
p
label First
input(name="first", type="text")
p
label Last
input(name="last", type="text")
p
label Email
input(name="email", type="text")
p
label Password
input(name="password", type="text")
p
button Submit
p
a(href="/") Go back
后端代码js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const controller = require('./controller');
const urlencodedParser = bodyParser.urlencoded({ extended: false });
app.get('/signup', (req, res) => {
res.render('signup');
});
app.post('/signup', urlencodedParser, controller.postSignUp);
app.listen(3000, () => {
console.log('start');
});
js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// controller/index.js
const model = require('../model/server');
exports.postSignUp = (req, res) => {
const { first, last, email, password} = req.body;
// 交由model来存储数据
model.insert({
first,
last,
email,
password
}, (num) => {
if (num === -1) {
res.redirect('/error'); // 这里其实是跳转错误界面,这些细节就不介绍了
return;
}
if (1 === num) {
res.redirect(`/login/${email}`);
return;
}
})
};
js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// model/server.js
const MongoClient = require("mongodb").MongoClient;
const url = "mongodb://localhost:27017";
const dbName = "student";
MongoClient.connect(url, function(err, client){
if (err) throw err;
const col = client.db(dbName).collection("classes");
// 插入数据
exports.insert = (data, next) => {
col.insertOne(data,
err => {
if (err) {
next(-1);
return;
}
next(1);
}
);
};
});
登录
登录界面pug1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
extends layout
block body
form(action="/login", method="POST")
fieldset
legend Log in
if (signupEmail)
p Congratulations on signing up! Please login below
p
label Email
input(name="email", type="text", value=signupEmail)
p
label Password
input(name="password", type="text")
p
button Submit
p
a(href="/") Go back
后端代码js1
2
3
4
5
6
7
8
9
10
11
12
...
app.get('/login', (req, res) => {
res.render('login');
});
app.get('/login/:signupEmail', (req, res) => {
res.render("login", { signupEmail: req.params.signupEmail });
});
app.post("/login", urlencodedParser, controller.postLogin);
...
js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// controller/index.js
...
exports.postLogin = (req, res) => {
const { email, password } = req.body;
model.find({ email, password }, (num, result) => {
if (-1 === num) {
res.redirect('/error');
}
if (0 === num) {
res.send('
Email or password is not correct. Go back and try again.
');return;
}
if (1 === num) {
// 存储用户信息
req.session.loggedIn = result._id.toString();
res.redirect('/');
}
});
}
...
js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// model/server.js
MongoClient.connect(url, function(err, client){
...
exports.find = (data, next) => {
col.findOne(
data,
(err, result) => {
if (err) {
next(-1);
return;
}
if (!result) {
next(0);
return;
}
next(1, result);
}
);
}
...
}
补充
其实项目中还有 logout 功能,显示用户功能没有讲,但是这些相对简单,因此就不展开了。
在登录的时候有一句req.session.loggedIn = result._id.toString();,如果想通过 id 查询数据,则
js1
2
3
4
5
const ObjectId = require("mongodb").ObjectId;
const ID= req.session.loggedIn;
model.find({_id: ObjectId(ID)}, (num, result) => {
//...
});
跟新于 19-05-23
使用mongoose替代mongodb保存数据, 具体文档参照mongoose 官网
主要改动在model/server.js
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
// model/server.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
mongoose.connect("mongodb://localhost/student", { useNewUrlParser: true });
const personSchema = new Schema(
{
first: String,
last: String,
email: {
type: String,
unique: true
},
password: {
type: String,
unique: true
}
},
{ autoIndex: false }
);
const Person = mongoose.model('classes', personSchema);
exports.insert = (data, next) => {
const person = new Person(data);
person.save(err => {
if (err) {
next(-1);
return;
}
next(1);
});
}
exports.find = (data, next) => {
Person.findOne(data, (err, result) => {
if (err) {
next(-1);
return;
}
if (!result) {
next(0);
return;
}
next(1, result);
});
}
补充
原来的 Mongodb 获取 ObjectId 转变成 Mongoose 方式
const ObjectId = require(“mongodb”).ObjectId;
const ObjectId = require(“mongoose”).Types.ObjectId;
总结
总的来说迈出了第一步😃 😃 😃
document.querySelectorAll('.github-emoji')
.forEach(el => {
if (! el.dataset.src) { return; }
const img = document.createElement('img');
img.style = 'display:none ! important;';
img.src = el.dataset.src;
img.addEventListener('error', () => {
img.remove();
el.style.color = 'inherit';
el.style.backgroundImage = 'none';
el.style.background = 'none';
});
img.addEventListener('load', () => {
img.remove();
});
document.body.appendChild(img);
});