Express框架与koa2框架差不多 参考Koa2框架

创建项目

1、创建文件夹(手动 || 命令)
命令为例:
mkdir BlogAPI

2、初始化项目
npm init -y

3、搭建express框架 项目框架默认是3000
npx express-generator

4、下载express依赖
npm i

5、npm start 启动 || nodemon start(开发时使用)

连接MySQL

下载依赖

npm i mysql

项目下创建db文件夹

image

创建config.js 配置数据库信息

let dbOption
dbOption = {
connectionLimit: 10,
host: 'localhost',//IP
user: 'root',//用户名
password: 'root',//密码
port: '3306',//端口
database: 'blogserver'//数据库名字
}
module.exports = dbOption

创建index.js 封装数据库方法

const mysql=require('mysql')
const dboptions= require('./config')
//创建连接池
const pool=mysql.createPool(dboptions);
//查询方法
function query(sql,params){
return new Promise((resolve,reject) => {
pool.getConnection((err,conn)=>{
if(err){
reject(err);
return;
}
//执行sql语句
conn.query(sql,params,(err,result)=>{
conn.release();
if(err){
reject(err);
return;
}
resolve(result);
})
})
})
}
module.exports=query

跨域请求

下载

npm i cors

配置app.js

const cors=require('cors');

app.use(cors());

MD5加密

下载

npm i crypto

项目根目录下创建utils文件夹

image

创建constan.js 存放常量的

module.exports={
//秘钥
PWD_SALT: 'SERVEBLOG'
}

创建index.js 封装加密的方法

const crypto=require('crypto')
//密码加密
function md5(str){
//参数为String类型
return crypto.createHash('md5').update(String(str)).digest('hex')
}
module.exports={
md5
}

注册接口示例

修改app.js的使用路由 /api/users

image

routers/users.js

/**
* 注册
*/
router.post('/register', async (req, res, next)=>{
//获取前台的数据
let {username, password,nickname,headimg} = req.body;
//为空就给默认的头像
headimg=headimg || 'https://gitee.com/xyhcodefilter/pic-go/raw/d514d8913c873b3c86329cb7d6f0cfbd18abab95/image/202204212057941.webp'
console.log(username,password,nickname,headimg);
//查询用户是否注册
try {
//根据用户名查询用户是否注册
let user=await querysql('select * from user where username = ?',[username]);
//没有注册
if(user.length === 0){
//加密
password=md5(`${password}${PWD_SALT}`);
//添加用户
let regresult=await querysql('insert into user (username,password,nickname,headimg) values (?,?,?,?)',[username,password,nickname,headimg]);
//查询添加后的用户信息
let userinfo=await querysql('select id,username,nickname,headimg from user where id=?',[regresult.insertId]);
//返回信息
res.send({
code: 201,
msg:'注册成功!',
data:userinfo[0]
})
}else{
res.send({
code:-1,
msg:'用户已注册!'
});
}
}catch (e) {
console.log(e);
//交给中间件
next(e);
}
});

创建token

下载

npm i jsonwebtoken

utils/constant.js 定义常量

//token秘钥
PRIVATE_KEY: 'xianxian',
//token过期时间 一天
EXPIRED:60*60*24

routers/users.js 导入常量和JWT

const {PWD_SALT,PRIVATE_KEY,EXPIRED}=require('../utils/constant')
const jwt=require('jsonwebtoken')

/**
* 登入
*/
router.post('/login',async (req,res,next) => {
let {username, password} = req.body;
try{
//根据用户名查询用户是否注册
let user=await querysql('select * from user where username = ?',[username]);
//没有找到
if(user.length === 0){
res.send({
code:-1,
msg:'用户不存在!'
});
}else{
//加密
password=md5(`${password}${PWD_SALT}`);
//查询验证账号密码是否正确
let seres=await querysql('select * from user where username = ? and password = ?',[username,password]);
//没有找到
if(seres.length === 0){
res.send({
code:-1,
msg:'账号或密码不正确!'
})
}else{//存在
//取出用户的信息
let sinresult=seres[0];
//生成token({存的变量},常量token秘钥,{过期时间})
let token=jwt.sign({sinresult},PRIVATE_KEY,{expiresIn:EXPIRED});
//保存返回的数据
let returnres={
id: seres[0].id,
username: seres[0].username,
nickname: seres[0].nickname,
headimg: seres[0].headimg,
token:`Bearer ${token}`
}
//console.log(returnres);
res.send({
code:200,
msg:'登入成功!',
data:returnres
})
}
}
}catch (e) {
console.log(e);
//交给中间件
next(e);
}
})

拦截验证token

下载

npm install express-jwt 

app.j
导入

//导入JWT
const {expressjwt: expressJWT} = require("express-jwt");
//constant.js常量
const {PRIVATE_KEY}=require('./utils/constant');

在路由前面验证拦截 app.js

//拦截验证
app.use(expressJWT({
//自定义的秘钥 constant.js
secret:PRIVATE_KEY,
algorithms: ["HS256"],
}).unless({
path:[
'/api/users/register',//白名单 除了这里的地址 其他URL都要验证
'/api/users/login'
]
}))

image

token错误异常 app.js

app.use(function(err, req, res, next) {
// set locals, only providing error in development
//token出现异常
if (err.name === 'UnauthorizedError') {
// 这个需要根据⾃自⼰己的业务逻辑来处理理
res.status(401).send({code:401,msg:'token验证错误!'});
}else {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
}
});

得到用户信息示例

请求需要传token

router.get('/info',async (req, res, next)=>{
//console.log(req.auth.sinresult);token中获取用户信息
let usid=req.auth.sinresult.id;//取出token中的用户ID
try {
//查询用户信息
let usinfo=await querysql('select id,username,nickname,headimg from user where id =?',[usid]);
res.send({
code:200,
msg:'用户信息获取成功!',
data:usinfo[0]
});
//console.log(usinfo);
}catch (e) {
next(e);
}
})

访问静态资源

http://127.0.0.1:3000/uploads/20220423/1650700417487.webp



uploads是public下的文件夹

头像上传

下载

npm install --save multer 

配置上传的方法
utils/index.js

const multer = require("multer");
const path = require("path");
const fs=require('fs')

//文件上传
let upload=multer({
storage:multer.diskStorage({
destination:function (req,file,cb) {
let date=new Date();
let year=date.getFullYear();
let month=(date.getMonth()+1).toString().padStart(2,'0')
let day=date.getDate();
let dir=path.join(__dirname,'../public/uploads/'+year+month+day);
if(!fs.existsSync(dir)){
fs.mkdirSync(dir,{recursive:true});
}
cb(null,dir);
},
//设置文件名
filename:function (req,file,cb) {
let filsname=Date.now()+path.extname(file.originalname);
cb(null,filsname);
}
})
})
module.exports={
upload
}

routes/users.js

const {md5,upload}=require('../utils/index')
/**
* 头像上传
*/
router.post('/uploads',upload.single('headimg'),async (req, res, next)=>{
console.log(req.file);
let imgpath=req.file.path.split('public')[1];
let imgurl=`http://${IP}:3000${imgpath}`;
res.send({
code:201,
msg:'上传成功!',
data:imgurl
})
})

不拦截
app.js

//拦截验证
app.use(expressJWT({
//自定义的秘钥
secret:PRIVATE_KEY,
algorithms: ["HS256"],
}).unless({
path:[
'/api/users/register',//白名单 除了这里的地址 其他URL都要验证
'/api/users/login',
'/api/users/uploads'//不拦截图片上传接口
]
}))

使用

//name等于upload.single('xxx')里面的xxx
<el-upload
action="http://127.0.0.1:3000/api/users/uploads"
list-type="picture-card" name="headimg" :on-success="resmk">
<i class="el-icon-plus"></i>
</el-upload>

用户更新信息示例

/**
* 更新用户信息
*/
router.put('/updateuser',async (req, res, next)=>{
let usid=req.auth.sinresult.id;//取出token中的用户ID
//获取数据
let {nickname,headimg}=req.body;
try {
//更新数据
let result=await querysql('update user set nickname=?,headimg=? where id=?',[nickname,headimg,usid]);
console.log(result);
//从新查询用户信息
let seresult=await querysql('select id,username,nickname,headimg from user where id=?',[usid]);
res.send({
code:200,
msg: '更新成功!',
data:seresult[0]
})
}catch (e) {
next(e)
}
})