项目介绍
一个提供 API 接口供开发者调用的平台。
用户可以注册登录,开通接口调用权限。用户可以浏览接口并调用,且每次调用会进行统计。
管理员可以发布接口、下线接口、接入接口,以及可视化接口的调用情况、数据。
项目侧重于后端,包含较多的编程技巧和架构设计层面的知识。、
项目资料
⭐️ API 开放平台项目源码:源码链接(后端)
第 1 集
主要内容:
- 项目介绍、业务流程、项目计划、需求分析
- 数据库表设计
- 前后端项目初始化(包含 Ant Design Pro 框架最新版本的使用)
- 前后端代码自动生成(强烈推荐,提高 1000% 的开发效率)
- 登录页、接口信息页开发
需求分析
背景:
- 前端开发需要用到后台接口
- 使用现成的系统的功能(搏天api-免费api接口平台)
做一个 API 接口平台:
- 管理员可以对接口信息进行增删改查
- 用户可以访问前台,查看接口信息
其他要求:
- 防止攻击(安全性)
- 不能随便调用(限制、开通)
- 统计调用次数
- 计费
- 流量保护
- API 接入
业务流程
技术选型
前端
- Ant Design Pro
- React
- Ant Design Pro components
- Umi
- Umi Request(Axios 的封装)
后端
- Spring Boot Starter(SDK 开发)
- Dubbo(RPC)
- Nacos
- Spring Cloud Gateway(网关、限流、日志实现)
-
数据库表设计
接口信息表
-- 接口信息 create table if not exists api.`interface_info` ( `id` bigint not null auto_increment comment '主键' primary key, `name` varchar(256) not null comment '名称', `description` varchar(256) null comment '描述', `url` varchar(512) not null comment '接口地址', `requestHeader` text null comment '请求头', `responseHeader` text null comment '响应头', `status` int default 0 not null comment '接口状态(0-关闭,1-开启)', `method` varchar(256) not null comment '请求类型', `userId` bigint not null comment '创建人', `createTime` datetime default CURRENT_TIMESTAMP not null comment '创建时间', `updateTime` datetime default CURRENT_TIMESTAMPnot null on update CURRENT_TIMESTAMP comment '更新时间', `isDelete` tinyint default 0 not null comment '是否删除(0-未删, 1-已删)' ) comment '接口信息';
项目脚手架
前端:ant design pro 脚手架(开箱即用的中台前端/设计解决方案 - Ant Design Pro)
后端:用的程序员鱼皮的后端模版代码
基础功能开发
增删改查、登录功能(通过复制粘贴完成)
前端接口调用:后端使用遵循 openapi 的规范的 swagger 文档,使用前端 Ant Design Pro 框架集成的 oneapi 插件自动生成。
第 2 集
主要内容:
- 开发接口管理前端页面
- 开发模拟 API 接口
- 开发调用接口客户端
- 保证调用的安全性(API 签名认证)
- 客户端 SDK 的开发(Spring Boot Starter 开发)
模拟接口项目
项目名称:yuapi-interface
提供三个不同种类的模拟接口:
- GET 接口
- POST 接口(url 传参)
- POST 接口(Restful)
调用接口
几种 HTTP 调用方式:
- HttpClient
- RestTemplate
- 第三方库(OKHTTP、Hutool)
Hutool:Hutool参考文档
Http 工具类:Hutool参考文档
API 签名认证
本质:
- 签发签名
- 使用签名(校验签名)
为什么需要?
- 保证安全性,不能随便一个人调用
- 适用于无需保存登录态的场景。只认签名,不关注用户登录态。
签名认证实现
通过 http request header 头传递参数。
参数 1:accessKey:调用的标识 userA, userB(复杂、无序、无规律)
参数 2:secretKey:密钥(复杂、无序、无规律) 该参数不能放到请求头中
(类似用户名和密码,区别:ak、sk 是无状态的)
大家可以自己写代码来给用户生成 ak、sk
千万不能把密钥直接在服务器之间传递,有可能会被拦截
参数 3:用户请求参数
参数 4:sign
加密方式:对称加密、非对称加密、md5 签名(不可解密)
用户参数 + 密钥 => 签名生成算法(MD5、HMac、Sha1) => 不可解密的值
abc + abcdefgh => sajdgdioajdgioa
怎么知道这个签名对不对?
服务端用一模一样的参数和算法去生成签名,只要和用户传的的一致,就表示一致。
怎么防重放?
参数 5:加 nonce 随机数,只能用一次
服务端要保存用过的随机数
参数 6:加 timestamp 时间戳,校验时间戳是否过期。
API 签名认证是一个很灵活的设计,具体要有哪些参数、参数名如何一定要根据场景来。(比如 userId、appId、version、固定值等)
思考:难道开发者每次调用接口都要自己写签名算法?
开发简单易用的 SDK(简历加分项)
项目名:yuapi-client-sdk
为什么需要 Starter?
理想情况:开发者只需要关心调用哪些接口、传递哪些参数,就跟调用自己写的代码一样简单。
开发 starter 的好处:开发者引入之后,可以直接在 application.yml 中写配置,自动创建客户端
Starter 开发流程
初始化,环境依赖(一定要移除 build):
spring-boot-configuration-processor 的作用是自动生成配置的代码提示
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
编写配置类(启动类):
@Configuration
@ConfigurationProperties(prefix = "yuapi.client")
@Data
@ComponentScan
public class YuApiClientConfig {
/**
* appId
*/
private String appId;
/**
* 秘钥
*/
private String appSecret;
/**
* 用户 id
*/
private String userId;
@Bean
public YuApiClient yuApiClient() {
return new YuApiClient(appId, appSecret, userId);
}
}
注册配置类,resources/META_INF/spring.factories 文件:
# spring boot starter
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.yupi.yuapiclientsdk.YuApiClientConfig
mvn install 打包代码为本地依赖包
创建新项目(复用 server 项目)、测试
小作业:把打好的包发到 maven 仓库中