1,新文件夹 配置
npm config set registry https://registry.npmmirror.com
npm i -y
npm install
npm i express@4.17.1
npm i cors
npm i mysql
npm i jsonwebtoken
npm i express-jwt
npm i joi express-joi
npm install bcrypt
2,目录创建如下
3.代码
3.1config文件夹,db文件夹
(1)config.js代码
module.exports = {
jwtSecretKey: 'itheima No1. ^_^',
}
(2)scret.js代码
exports.secret = 'aaaaaaaa'
(3)db里面index.js代码
const mysql = require('mysql')
const db = mysql.createPool({
host: '127.0.0.1',
user: 'root',
password: '123456',
database: 'my_db_01',
port:"3308"
})
module.exports = db
3.2 router文件夹
(1)books.js
const express = require('express')
const router = express.Router()
const bookhandler = require('../router_handler/books')
router.get('/getbooks', bookhandler.getbooks)
router.post('/addbook', bookhandler.addbook)
router.get('/delbook', bookhandler.delbook)
module.exports = router
(2)user.js代码
const express = require('express')
const router = express.Router()
// 导入用户路由处理函数模块
const userHandler = require('../router_handler/user')
// 1. 导入验证表单数据的中间件
const expressJoi = require('@escook/express-joi')
// 2. 导入需要的验证规则对象
const { reg_login_schema } = require('../schema/user')
// 注册新用户
// 3. 在注册新用户的路由中,声明局部中间件,对当前请求中携带的数据进行验证
// 3.1 数据验证通过后,会把这次请求流转给后面的路由处理函数
// 3.2 数据验证失败后,终止后续代码的执行,并抛出一个全局的 Error 错误,进入全局错误级别中间件
router.post('/reguser', expressJoi(reg_login_schema), userHandler.regUser)
// 登录
router.post('/login', expressJoi(reg_login_schema), userHandler.Login)
module.exports = router
(3)userinfo.js代码
const express = require('express')
const router = express.Router()
const multer = require('multer')
const upload = multer({ dest: 'photo/' })
// 导入用户信息的处理函数模块
const { update_avatar_schema } = require('../schema/user')
const userinfo_handler = require('../router_handler/userinfo')
// 获取用户的基本信息
router.get('/userinfo', userinfo_handler.getUserInfo)
const expressJOT = require('@escook/express-joi')
const { update_userinfo_schema, update_password_schema } =require('../schema/user')
// router.post('/post', photo.single('corer'), (req, res) => {
// console.log(req.file)
// res.send({ name: '我是post响应过去的数据formdata' })
// })
router.post('/userinfo', expressJOT(update_userinfo_schema),userinfo_handler.updateUserInfo)
router.post('/updatepwd', expressJOT(update_password_schema),userinfo_handler.updatePassword)
router.post('/update/avatar',upload.single('corer'), userinfo_handler.updateAvatar)
module.exports = router
(4)users.js代码
const express = require('express')
const router = express.Router()
const userHandler = require('../router_handler/user')
router.post('/my/reguser', userHandler.regUser)
router.post('/my/login', userHandler.Login)
module.exports = router
3.3router_handler代码
(1)books.js代码
const db = require('../db/index')
exports.getbooks = (req, res) => {
let sql = 'select * from books'
db.query(sql, (err, rst) => {
if (err) return res.send({
status: 500,
msg: '获取图书列表失败'
})
res.send({
status: 200,
msg: '获取图书列表成功',
data: rst,
username:req.user.username
})
})
}
exports.addbook = (req, res) => {
let books = req.body
let sql = 'insert into books set ?'
db.query(sql, books, (err, rst) => {
if (err) return res.send({
status: 500,
msg: '添加图书失败'
})
if (rst.affectedRows != 1) {
return res.send({
status: 500,
msg: '添加图书失败'
})
}
res.send({
status: 201,
msg: '添加图书成功'
})
})
}
exports.delbook = (req, res) => {
let id = req.query.id
if (!id) return res.send({
status: 500,
msg: '未指定要删除的图书Id'
})
let sql = 'delete from books where id=?'
db.query(sql, id, (err, rst) => {
if (err) return res.send({
status: 501,
msg: 'sql执行错误'
})
if (rst.affectedRows != 1) return res.send({
status: 502,
msg: '要删除的图书不存在'
})
res.send({
status: 200,
msg: '删除图书成功'
})
})
}
(2)user.js代码
const jwt = require('jsonwebtoken')
const db = require('../db/index')
const scret = require('../config/scret')
const bcryptjs = require('bcryptjs')
exports.regUser = (req, res) => {
let user = req.body
let sql1 = 'select * from users where username=?'
db.query(sql1, user.username, (err, rst) => {
if (err) return res.send({
status: 201,
msg: 'sql1执行错误'
})
if (rst.length > 0) {
return res.send({
status: 202,
msg: '用户名存在'
})
}
let sql2 = 'insert into users set ?'
user.password = bcryptjs.hashSync(user.password, 10)
// console.log(user)
db.query(sql2, user, (err, rst) => {
if (err) return res.send({
status: 201,
msg: 'sql2执行错误'
})
if (rst.affectedRows != 1) return res.send({
status: 203,
msg: '注册失败'
})
return res.send({
status: 200,
msg: '注册成功'
})
})
})
}
exports.Login = (req, res) => {
let user = req.body
// user.password = bcryptjs.hashSync(user.password, 10)
// console.log(user.password)
let sql = 'select * from users where username=?'
db.query(sql, [user.username], (err, rst) => {
if (err) return res.send({
status: 201,
msg: 'sql执行错误'
})
if (rst.length == 0) {
return res.send({
status: 201,
msg: '用户名或密码误'
})
}
let compare = bcryptjs.compareSync(user.password, rst[0].password)
if (!compare) {
return res.send({
status: 201,
msg: '用户名或密码误'
})
}
const tokenstr = jwt.sign({ username: user.username }, scret.secret, { expiresIn: '10h' })
res.send({
status: 200,
msg: '登录成功',
token: 'Bearer ' + tokenstr
})
})
}
(3)userinfo.js代码
const db = require('../db/index')
exports.updateAvatar = (req, res) => {
console.log(req.file)
const sql = 'update ev_users set user_pic=? where id=?'
db.query(sql, [req.file.path, req.user.id], (err, results) => {
// 执行 SQL 语句失败
if (err) return res.cc(err)
// 执行 SQL 语句成功,但是影响行数不等于 1
if (results.affectedRows !== 1) return res.cc('更新头像失败!')
// 更新用户头像成功
return res.cc('更新头像成功!', 0)
})
}
3.3schema文件夹
(1)user.js代码
const joi = require('joi')
/**
* string() 值必须是字符串
* alphanum() 值只能是包含 a-zA-Z0-9 的字符串
* min(length) 最小长度
* max(length) 最大长度
* required() 值是必填项,不能为 undefined
* pattern(正则表达式) 值必须符合正则表达式的规则
*/
// 用户名的验证规则
const username = joi.string().alphanum().min(1).max(10).required()
// 密码的验证规则
const password = joi
.string()
.pattern(/^[\S]{6,12}$/)
.required()
// 注册和登录表单的验证规则对象
exports.reg_login_schema = {
// 表示需要对 req.body 中的数据进行验证
body: {
username,
password,
},
}
const avatar = joi.string().dataUri().required()
exports.update_avatar_schema = {
file: {
avatar,
},
}
3.4app.js代码
const express = require('express')
const app = express()
const cors = require('cors')
const bookrouter = require('./router/books')
const userrouter = require('./router/users')
const expressJWT = require('express-jwt')
const scret = require('./config/scret')
app.use(cors())
app.use(express.urlencoded({ extended: false }))
app.use(expressJWT({ secret: scret.secret }).unless({ path: [/^\/api\/my\//] }))
app.use('/api', bookrouter)
app.use('/api', userrouter)
app.use((err, req, res, next) => {
if (err.name == 'UnauthorizedError') return res.send({
status: 500,
msg: 'token验证失败'
})
if (err instanceof joi.ValidationError) return res.send({
status:500,
msg:err
})
res.send({
status: 501,
msg: '未知错误'
})
})
app.listen(3006, () => {
console.log('server running@127.0.0.1:3006')
})
3.5package.json代码
{
"name": "api_server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@escook/express-joi": "^1.1.1",
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"express": "^4.17.1",
"express-jwt": "^5.3.3",
"joi": "^17.11.0",
"jsonwebtoken": "^9.0.2",
"mysql": "^2.18.1"
}
}