1. 业务场景
我们以一个简化版的电商网站项目为例,其中涉及到6块功能,分别是登录、添加商品、商品列表、下订单、我的订单、订单详情,每个功能都有相应的权限限制,并且调用对应的接口来做相应的业务逻辑处理,完成后跳转到下一页面。具体页面/功能、权限、调用接口、动作及跳转的逻辑关系如下:
| 页面 |
权限 |
调用接口 |
动作及跳转 |
| 1登录 |
所有用户 |
login |
点击【登录】->商品页 |
| 2添加商品 |
管理员权限 |
add_product |
无 |
| 3商品列表 |
所有用户 |
get_product |
点击【下单】->订单 |
| 4订单 |
订单所属用户 |
order |
点击【支付】->我的订单 |
| --支付 |
订单所属用户 |
mock |
--点击【支付完成】->我的订单 |
| 5我的订单 |
订单所属用户 |
user_orderid |
点击【订单区域】->订单详情 |
| 6订单详情 |
订单所属用户 |
get_order |
无 |
项目的设计遵循前后端完全分离的设计模式,前端可以是Web、iOS、Android、小程序各种类型的客户端,但后端接口都是一致的,因此我们用代码实现上述6个接口功能,然后开发Web网站调用接口的实现电商下单购买支付的流程,并列举两个其中比较典型的安全问题,项目示例代码参见GitHub:https://github.com/8784285/order_web.git 。
2. 接口文档
1) 登录
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| username |
string |
是 |
字母数字_.组合,长度2-20 |
Mr.null |
| password |
string |
是 |
MD5加密,长度32 |
|
{
"username": "Mr.null",
"password": "dc483e80a7a0bd9ef71d8cf973673924"
}
| 参数名 |
类型 |
是否必需 |
备注 |
示例 |
| code |
number |
是 |
4:成功;2:失败 |
4 |
| msg |
string |
是 |
登录成功/非法用户 |
"登录成功" |
| token |
string |
是 |
|
|
{
"code": 4,
"msg": "登录成功",
"token": "eyJhbGciOiJIUzUxMiIsImlhdCI6MTU5MTgzNzQ0MSwiZXhwIjoxNTkxOTIzODQxfQ.eyJ1c2VybmFtZSI6Ik1yLm51bGwiLCJwYXNzd29yZCI6ImRjNDgzZTgwYTdhMGJkOWVmNzFkOGNmOTczNjczOTI0In0.fJVi3MZXmEz9lue0gZUO0m_lG2I-8endYsGOP4FNCGZ9wdGpKDb-yDNGj9XCrRXtoIz0AGIh-v-_oPWeOSYspQ"
}
2) 添加商品
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| name |
string |
是 |
字母数字_.组合,长度2-20 |
Mr.null |
| price |
number |
是 |
保留两位小数 |
25.50 |
| count |
count |
是 |
>0的整数 |
100 |
{
"name":"Book",
"price":16.50,
"count":100
}
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| Authorization |
string |
是 |
请求授权头 |
XDS 7.dVkI-SQWxjICYXD_TE54hZGIZwVud18LfXew-Ioorg0 |
| 参数名 |
类型 |
是否必需 |
备注 |
示例 |
| code |
number |
是 |
2001:成功;2002:失败 |
2001 |
| msg |
string |
是 |
商品添加成功/商品添加失败 |
"商品添加成功" |
{
"code": 2001,
"msg": "商品添加成功"
}
3)商品列表
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| name |
string |
否 |
不传则默认返回20个商品 |
Book |
http://127.0.0.1:5000/get_product?name=Book
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| Authorization |
string |
是 |
请求授权头 |
XDS 7.dVkI-SQWxjICYXD_TE54hZGIZwVud18LfXew-Ioorg0 |
| 参数名 |
类型 |
是否必需 |
备注 |
示例 |
| code |
number |
是 |
5:成功;6:失败 |
5 |
| msg |
string |
是 |
查询成功/未查询到数据 |
"查询成功" |
| data |
object |
是 |
包含count、name、price的1到多个字典 |
|
{
"code": 5,
"data": {
"count": 100,
"name": "Book",
"price": 12.5
},
"msg": "查询成功"
}
4)提交订单
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| sid |
number |
是 |
>0的整数 |
12 |
| orderprice |
number |
是 |
商品价格,保留两位小数 |
37.50 |
| username |
string |
是 |
登录用户的用户名 |
Mr.null |
| receiver |
string |
是 |
收件人 |
张三 |
| phone |
string |
是 |
电话 |
13800138000 |
| address |
string |
是 |
收件地址 |
北京市海淀区长安街888号 |
{
"sid":11,
"orderprice":39.50,
"username":"admin",
"receiver":"张三",
"phone":"13800138000",
"address":"北京市海淀区长安街888号"
}
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| Authorization |
string |
是 |
请求授权头 |
XDS 7.dVkI-SQWxjICYXD_TE54hZGIZwVud18LfXew-Ioorg0 |
| 参数名 |
类型 |
是否必需 |
备注 |
示例 |
| code |
number |
是 |
2003:成功;2004:失败 |
2003 |
| msg |
string |
是 |
订单创建成功/订单创建失败 |
"订单创建成功" |
{
"code": 2003,
"msg": "创建订单成功"
}
5)获取用户订单
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| username |
string |
是 |
登录用户的用户名 |
Mr.null |
http://192.168.160.94:5000/user_orderid?username=Mr.null
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| Authorization |
string |
是 |
请求授权头 |
XDS 7.dVkI-SQWxjICYXD_TE54hZGIZwVud18LfXew-Ioorg0 |
| 参数名 |
类型 |
是否必需 |
备注 |
示例 |
| code |
number |
是 |
2003:成功;2004:失败 |
2003 |
| msg |
string |
是 |
订单创建成功/订单创建失败 |
"订单创建成功" |
| orderid |
object |
是 |
用户订单编号列表,最多20条 |
|
{
"code": 5,
"msg": "查询成功",
"orderid": [
1,
2
]
}
6)订单详情
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| productid |
number |
是 |
>0的整数 |
12 |
http://192.168.160.94:5000/get_order?productid=12
| 参数名 |
类型 |
是否必填 |
备注 |
示例 |
| Authorization |
string |
是 |
请求授权头 |
XDS 7.dVkI-SQWxjICYXD_TE54hZGIZwVud18LfXew-Ioorg0 |
| 参数名 |
类型 |
是否必需 |
备注 |
示例 |
| code |
number |
是 |
5:成功;6:失败 |
5 |
| msg |
string |
是 |
查询成功/未查询到结果 |
"查询成功" |
| orderid |
object |
是 |
包含count、name、price等用户订单详情字典 |
|
{
"code": 5,
"data": {
"count": 100,
"name": "Book",
"price": 12.5
},
"msg": "查询成功"
}
3. 数据库结构
电商项目数据库共包含4个表,分别是
- stock:商品信息表
- stock_order:订单信息表
- users:用户表
- userinfo:用户详情信息表
数据库表结构及初始化数据如下(sql详见GitHub:)
-- phpMyAdmin SQL Dump
-- ve