我们利用node+express+mysql开发接口,对数据库数据进行简单增、删、查改等操作。
下面做一个书城商店api案例(大概有个人信息模块,书产品分类模块,购物车模块,信息资讯),利用宝塔工具将api部署到服务器,利用cdn访问图片,富文本编辑器使用等。(vue3)一边做uniapp开发小程序一边写接口,可能会写后台管理系统(看时间)。为了节约时间不用ts,后面有时间再用ts优化ᥬ᭄。
工具
数据库可视化
接口测试工具Postman
我们这里利用node+express+mysql开发一个简单的书城商店API。后面会使用result API规范接口
新建文件夹server 安装依赖
npm init -y
安装依赖express
npm i express
新建app.js作为入口文件创建服务器实例
// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()
// write your code here...
// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(8000, function () {
console.log('server running at http://127.0.0.1:8000')
})
安装nodemon
npm i nodemon
npm i cors
在app.js中导入并配置cors中间件:
// 导入 cors 中间件
const cors = require('cors')
// 将 cors 注册为全局中间件
app.use(cors())
通过如下的代码,配置解析application/x-www-form-urlencoded格式的表单数据的中间 件:
app.use(express.urlencoded({ extended: false }))
4、初始化路由
路由模块中,只存放客户端的请求与处理函数之间的映射关系
路由处理函数模块中,专门负责存放每个路由对应的处理函数
例如:新建用户user路由模块
在入口文件中注册路由
访问接口(确保服务在运行),没有运行访问不了服务
我们需要在数据库进行存储数据,对数据进行操作,这里使用Mysql,后面改进会使用一个更好用的MongoDB
npm i mysql
2.创建数据库book,并创建一个用户users表格
新建数据库
创建users表格
新建db文件夹在其创建index.js连接数据库
// 导入 mysql 模块
const mysql = require('mysql')
// 创建数据库连接对象
const db = mysql.createPool({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'book',
})
// 向外共享 db 数据库连接对象
module.exports = db
1.实现步骤
1. 检测表单数据是否合法
2. 检测用户名是否被占用
3. 对密码进行加密处理
4. 插入新用户
2.检测表单数据是否合法
1. 判断用户名和密码是否为空
// 接收表单数据
const userinfo = req.body
// 判断数据是否合法
if (!userinfo.username || !userinfo.password) {
return res.send({ status: 1, message: '用户名或密码不能为空!' })
}
2 检测用户名是否被占用
1. 导入数据库操作模块:
const db=require('../db/index')
2. 定义 SQL 语句:
2.定义SQL语句
const sql=`select * from users where username=?`
3. 执行 SQL 语句并根据结果判断用户名是否被占用:
db.query(sql, [userinfo.username], function (err, results) {
// 执行 SQL 语句失败
if (err) {
return res.send({ status: 1, message: err.message })
}
// 用户名被占用
if (results.length > 0) {
return res.send({ status: 1, message: '用户名被占用,请更换其他用户名!' })
}
// TODO: 用户名可用,继续后续流程...
})
4.对密码进行加密处理
为了保证密码的安全性,不建议在数据库以明文的形式保存用户密码,推荐对密码进行加密 存储
在当前项目中,使用bcryptjs对用户密码进行加密,优点:
加密之后的密码,无法被逆向破解
同一明文密码多次加密,得到的加密结果各不相同,保证了安全性
npm i bcryptjs
在/router_handler/user.js中,导入bcryptjs:
const bcrypt=require('bcryptjs')
在注册用户的处理函数中,确认用户名可用之后,调用bcrypt.hashSync(明文密码, 随机盐的 长度)方法,对用户的密码进行加密处理:
// 对用户的密码,进行 bcrype 加密,返回值是加密之后的密码字符串
userinfo.password=bcrypt.hashSync(userinfo.password, 10)
5.插入新用户
const sql='insert into users set ?'
调用db.query()执行 SQL 语句,插入新用户:
db.query(sql, { username: userinfo.username, password: userinfo.password }, function
(err, results) {
// 执行 SQL 语句失败
if (err) return res.send({ status: 1, message: err.message })
// SQL 语句执行成功,但影响行数不为 1
if (results.affectedRows !== 1) {
return res.send({ status: 1, message: '注册用户失败,请稍后再试!' })
}
// 注册成功
res.send({ status: 0, message: '注册成功!' })
})
全部代码
/**
* 在这里定义和用户相关的路由处理函数,供 /router/user.js 模块进行调用
*/
const db = require('../db/index')
const bcrypt = require('bcryptjs')
// 注册用户的处理函数
exports.regUser = (req, res) => {
// 接收表单数据
const userinfo = req.body
// 判断数据是否合法
if (!userinfo.username || !userinfo.password) {
return res.send({ status: 1, message: '用户名或密码不能为空!' })
}
const sql = `select * from users where username=?`
db.query(sql, [userinfo.username], function (err, results) {
// 执行 SQL 语句失败
if (err) {
return res.send({ status: 1, message: err.message })
}
// 用户名被占用
if (results.length > 0) {
return res.send({ status: 1, message: '用户名被占用,请更换其他用户名!' })
}
// 对用户的密码,进行 bcrype 加密,返回值是加密之后的密码字符串
userinfo.password = bcrypt.hashSync(userinfo.password, 10)
const sql = 'insert into users set ?'
db.query(sql, { username: userinfo.username, password: userinfo.password }, function
(err, results) {
// 执行 SQL 语句失败
if (err) return res.send({ status: 1, message: err.message })
// SQL 语句执行成功,但影响行数不为 1
if (results.affectedRows !== 1) {
return res.send({ status: 1, message: '注册用户失败,请稍后再试!' })
}
// 注册成功
res.send({ status: 0, message: '注册成功!' })
})
})
}
// 登录的处理函数
exports.login = (req, res) => {
res.send('login OK')
}
为了方便测试接口我们允许其他字段为空
一开始表里没有数据
我们去测试注册功能(一定要配置解析表单数据的中间件)
注册功能完成
核心实现思路:调用bcrypt.compareSync(用户提交的密码, 数据库中的密码)方法比较密码是 否一致
返回值是布尔值(true 一致、false 不一致)
const userinfo = req.body
const sql = `select * from users where username=?`
db.query(sql, userinfo.username, function (err, results) {
// 执行 SQL 语句失败
if (err) return res.cc(err)
// 执行 SQL 语句成功,但是查询到数据条数不等于 1
if (results.length !== 1) return res.send('登录失败!')
// TODO:判断用户输入的登录密码是否和数据库中的密码一致
// 拿着用户输入的密码,和数据库中存储的密码进行对比
const compareResult = bcrypt.compareSync(userinfo.password, results[0].password)
// 如果对比的结果等于 false, 则证明用户输入的密码错误
if (!compareResult) {
return res.send('登录失败!')
}
return res.send('登录成功!')
})
基础登录接口实现