【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (一):项目简介及安装依赖
本项目旨在学习如何快速使用 nodejs 开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师)
由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序(并非循序渐进的教学文档)。建议配合项目源码node-mongodb-template 。
目标:使用nodejs+mongoDB编写一款后端API的模版Demo,方便以后使用。
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (一):项目简介及安装依赖
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (二):项目文件夹架构及路由的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (三):Cors的设置及.env文件的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (四):状态码的使用
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (五):POST上传文件的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (六):token的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (七):MongoDB的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (八):API说明(暂时完结,后续考虑将在线版mongoDB变为本地版)
案例说明:
存在3个类
Product : (id , name, price, productImage:String/URL;
Order : (id, product, quantity:Number);
User : (id, email, password)
order和product存在关联。
需要提供的API:products,orders的增删改查,user的注册、登录和删除。
业务:存在user登录状态下,才能成功执行部分信息的增删改查。(token)
开始开发
测试API使用postman软件
依赖
通篇使用了pnpm代替npm。
首先,新建文件夹作为工程文件,然后终端执行 pnpm i
, 初始化工程(创建package.json文件)。
本文使用的全部依赖如下
"dependencies": {
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.5.2",
"morgan": "^1.10.0",
"multer": "1.4.5-lts.1"
},
"devDependencies": {
"nodemon": "^3.1.4"
}
express
pnpm i --save express
web应用框架
可以使用如下代码
http
//require('http').createServer(app).listen(port)
const http = require('http');
const app = require("./app")
const port = process.env.PORT || 3000;
const server = http.createServer(app);
server.listen(port);
app.use
//app.use(....);
const express = require('express');;
const app = express();
app.use((req,res,next) => {
const error = new Error("NOT FOUND");
error.status = 404;
next(error);
})
app.use((error,req,res,next)=>{
res.status(error.status || 500);
res.json({
error:{
message:error.message
}
});
})
router
//router -> express.Router()
const express = require('express');
const router= express.Router();
router.get('/',(req,res,next) => {
});
nodemon
通常情况下,我们修改代码之后需要重启服务进行测试,使用如下终端指令
node server.js
但是nodemon可以帮助修改后自动重启服务。
-
终端安装依赖
pnpm i --save nodemon
; -
Package.json文件中修改代码如下
"scripts": {
...
"start": "nodemon server.js"
},
- 终端输入
pnpm start
, 显示如下code
> nodemon server.js
[nodemon] 3.1.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,cjs,json
[nodemon] starting `node server.js`
- 修改代码后保存,终端自动刷新如下code
[nodemon] restarting due to changes...
[nodemon] starting `node server.js`
morgan
日志打印,可以记录请求动作等
-
终端安装依赖
pnpm i --save morgan
-
app.js中引用
//app.js
const morgan = require('morgan');
app.use(morgan('dev'));
- 测试api, 以 localhost:3000/products 为例
成功请求后,终端显示code
//dev GET /products 200 3.494 ms - 36
不同的请求会显示不同的log
body-parser
请求解析模版,提取请求中的主体信息,并放入req.body
中
-
终端安装依赖
pnpm i --save body-parse
-
app.js中应用
//app.js
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended:false}));
app.use(bodyParser.json());
- Api请求中使用req.body获取请求中的信息,以routers/products.js为例
//routers/products.js
router.post('/',(req,res,next) => {
const name = req.body.name;
const price = req.body.price;
console.log(name + ',' + price);
})
- 测试,在postman中选择post请求,然后 localhost:3000/products ,body中选择raw/json, 然后如下如下代码
{
"name":"123",
"price":12
}
请求成功可以获得结果123,12
dotenv
创建环境变量存储文件.env
- 安装依赖
pnpm i --save dotenv
- 引用依赖
注意:1、在app.js
或server.js
文件中引用依赖;2、必须写在所有引用的最上方
//app.js
require("dotenv").config();
...
- .env文件内容
MONGO_ATLAS_PW=123
JWT_KEY=111
- 变量使用
process.env.MONGO_ATLAS_PW
bcrypt
在Node.js 中安全地对密码进行哈希处理
- 安装依赖
pnpm i --save bcrypt
- 引用依赖
const bcrypt = require('bcrypt');
- 使用
//加密
//将输入的密码进行加密,salt为10;
//回调如果是hash,加密成功,hash为生成的salt
bcrypt.hash(req.body.password,10,(err,hash) => {
if(err){
...
}else{
const user = new User({
_id:new mongoose.Types.ObjectId(),
email:req.body.email,
password:hash//成功加密后的结果
});
}
});
//比较
//比较输入的密码和数据库中的密码是否一致
//result结果为true说明两者加密形式一致,后续在通过json web token进行处理
bcrypt.compare(req.body.password,user[0].password,(err,result) => {
if(err){
...
}
if(result){
...解析成功
}
})
jsonwebtoken
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概流程:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
实施 Token 验证的方法挺多的,还有一些标准方法,比如 JWT(JSON Web Tokens) 。JWT 标准的 Token 有三个部分:
- header(头部)--- 加密算法
- payload(数据)--- 具体内容
- signature(签名)--- key
中间用点分隔开,并且都会使用 Base64 编码,所以真正的 Token 看起来像这样:
eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
应用步骤
- 安装依赖
pnpm i --save jsonwebtoken
- 定义key
定义环境变量 JWT_KEY
//.env
JWT_KEY=***
- 引用依赖
const jwt = require('jsonwebtoken');
- 加密和校验
token <== 基本信息 + key
token + key ==> 基本信息
//jwt.sign()
//token <== 基本信息 + key
//参数1:基本信息;参数2:key;参数3:过期时间
const token = jwt.sign({
email:user[0].email,
userId:user[0]._id
},process.env.JWT_KEY,{
expiresIn:"1h",
});
//jwt.verify()
//token + key ==> 基本信息
const decoded = jwt.verify(token,process.env.JWT_KEY);
multer
使用依赖 Multer
上传文件,用于处理 multipart/form-data
类型的表单数据。
详见POST文件的设置