首页 > 其他分享 >API 接口设计最佳实践

API 接口设计最佳实践

时间:2023-12-19 20:37:11浏览次数:40  
标签:加密 timestamp 校验 接口 sign 最佳 Token API

前言

 

最近团队内部在做故障复盘的时候发现有很多故障都是因为接口设计不当导致的,这里我就整理归纳一下在接口设计层面需要注意的地方。


API 接口设计

Token 设计

 

Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个 Token 便将此 Token 返回给客户端,以后客户端只需带上这个 Token 前来请求数据即可,无需再次带上用户名和密码。

 

Token 的值一般用 UUID(算法比较著名的有雪花算法),当服务端接收到客户端请求后会生成 Token(一串字符,如 etye0fgkgk4ca2ttdsl0ae9a5dd77471fgf),然后将 Token 作为 key 将一些和 Token 关联的信息作为 value 保存到如 Redis 缓存数据库中,同步把该 Token 返回给客户端;后续该客户端的请求都需要带上这个 Token,服务器收到请求后就会去缓存服务器中匹配这个 Token 是否存在,存在则调用接口,不存在返回接口错误。

 

Token 种类

 

API Token(接口令牌): 一般用于访问不需要用户登录的接口,如登录、注册、一些基本数据的获取(如信用卡官网的如信用卡费率相关信息)等。获取接口令牌需要拿 appId、timestamp 和 sign 来换;其中该 sign 值一般是把 timestamp、key 和对应的参数先进行字母排序再进行 MD5 加密(有时候会加盐),即 sign=MD5(排序(timestamp+key+参数));

  • 假设 API 的请求参数为 channel:T,discount:90%,quantities:10,根据参数名称的 ASCII 码表的顺序排序即为:channel:T,discount:90%,quantities:10。

  • 接着把排序后的参数名和参数值拼装在一起为:channelTdiscount90%quantities10。

  • 把拼装好的字符串采用 utf-8 编码,使用签名算法对编码后的字节流进行摘要,即为 sign=md5(channelTdiscount90%quantities10);

  • 最后,Token=hex(appid+sign+timestamp+salt),即可获得十六进制的一串字符,如“68656C6C6F776F726C64”。

 

USER Token(用户令牌): 用于访问需要用户登录之后的接口,如:获取我的基本信息、保存、修改、删除等操作。获取用户令牌需要拿用户名和密码来换。

 

API 接口设计原则

 

1、明确协议规范

 

在设计初期需要明确双方的通讯协议是 TCP、HTTP、RPC,一般针对比较敏感的交易或者行业(如金融业),建议使用 HTTPS 协议以确保数据交互的安全。

 

2、统一接口路径规范

 

建议采用 Restful 的风格,一般采用这样的格式:控制器名/方法名。具体请参考以下例子:

POST /recommend/cardlist

3、统一接口版本管理

 

APP 后台逻辑总是处于变化当中,但是 APP 端(如安卓和 ios)因为涉及到应用市场的审核问题,还有这些 2C 端的 APP 应用存在版本碎片化的问题,因此后台暴露的接口需要在一段时间内支持不同版本的接口,一般方法是通过 Nginx 通过配置过滤根据接口的不同版本进行路由分发。

 

一般来说,接口的版本管理一般有以下两种方法:

 

  1. 在 URL 中加入 version 信息,如下述;

  2. 在 HTTP header 加入 version 信息,这样就等于只有一个接口,但是具体的不同版本的业务逻辑由后台区分处理。

POST v1/recommend/cardlist

 

Nginx的路由分发:

server {

listen 80;

server_name vip.com;

location /v1/ {

proxy_pass http://129.0.0.1:8001/;

proxy_redirect http://129.0.0.1:8001/ /v1/;

proxysetheader Host $host;

}

location /v2/ {

proxy_pass http://129.0.0.1:8002/;

proxy_redirect http://129.0.0.1:8002/ /v2/;

proxysetheader Host $host;

}

}

 

server {

listen 8001;

allow 129.0.0.1;

deney all;

server_name vip.com;

root vip.com/v1/;

}

 

server {

listen 8002;

allow 129.0.0.1;

deney all;

server_name vip.com;

root vip.com/v2/;

}

4、为你的接口设定调用门槛

 

为调用你的系统分配一个 ID 和 key,针对每个请求对 ID 和 key 进行校验,避免在企业内网中的其他系统只要知道接口被可以随意调用。

 

5、接口返回规范

 

返回数据尽量统一规范,务必包括:返回码、返回信息、数据。

 

{

"code" : 0,

"content" : "string", <- 这里为 JSON

"message" : "string"

}

 

6、接口安全规范

 

当我们开发的接口需要暴露到公网,这样的风险跟我们在企业内网暴露给其他系统调用的风险是不可同日而语的。其中有很多风险需要我们一一解决。以下仅提供能想到的:

 

6.1.数据如何防止被看到?

目前业界老生常谈就是对称加密和非对称加密。

 

对称加密:对称密钥在加密和解密的过程中使用的密钥是相同的,常见的对称加密算法有 DES,AES;优点是计算速度快,缺点是在数据传送前,发送方和接收方必须商定好秘钥,然后使双方都能保存好秘钥,如果一方的秘钥被泄露,那么加密信息也就不安全了;

 

非对称加密:服务端会生成一对密钥,私钥存放在服务器端,公钥可以发布给任何人使用;优点就是比起对称加密更加安全,但是加解密的速度比对称加密慢太多了;广泛使用的是 RSA 算法;

 

目前主流的做法是在传输层使用 https 协议,http 和 tcp 之间添加一层加密层(SSL 层),这一层负责数据的加密和解密。https 协议则是巧妙的利用上述两种对称加密方法;浅显一点说就是客户端和服务端建立三次握手连接过程中通过交换双方非对称公钥,接着使用对方非对称公钥加密双方约定好的对称密钥,这样就只有双方有这个对称密钥(这样的非对称加密可以保证很安全的把对称密钥给到对方)。后续双方的报文沟通就可以使用该对称密钥进行加解密(这样的对称加密可以保证请求报文可以快速被解密处理,并在处理后被快速加密响应回去)。

6.2.数据如何防止给篡改?

这个时候我们需要对数据进行加签,数据签名平时用得比较多的是 MD5,即将需要提交的数据通过某种方式组合和一个字符串,然后通过 MD5 生成一段加密字符串,这段加密字符串就是数据包的签名。具体请看以下的图。

 

6.3.时间戳机制

如果加密数据被抓包后被用于重放攻击,我们怎么办?这个时候我们可以把解密后的 URL 参数中的时间戳与系统时间进行比较,如果时间差超过一定间距(如 5 分钟)即认为该报文被劫持并返回错误。但是,务必保证该时间戳的超时时间一定要跟 sign 保存的有效时间一致。

 

客户端在第一次访问服务端时,服务端将 sign 缓存到 Redis 中并把有效时间设定为跟时间戳的超时时间一致;如果有人使用同一个 URL 再次访问,如果发现缓存服务器中已经存在了本次的 sign,则拒绝服务;如果在 Redis 中的 sign 失效的情况下,有人使用同一个 URL 再次访问,则会被时间戳超时机制拦截。这样的话,就可以避免 URL 被别人截获后的重放攻击。

 

整个流程如下:

1、客户端通过用户名密码登录服务器并获取 Token

2、客户端生成时间戳 timestamp,并将 timestamp 作为其中一个参数

3、客户端将所有的参数,包括 Token 和 timestamp 按照自己的算法进行排序加密得到签名 sign

4、将 token、timestamp 和 sign 作为请求时必须携带的参数加在每个请求的 URL 后边(http://url/request?token=123&timestamp=123&sign=123123123)

5、服务端写一个过滤器对 token、timestamp 和 sign 进行验证,只有在 token 有效、timestamp 未超时、缓存服务器中不存在 sign 三种情况同时满足,本次请求才有效。

6.4.随机数机制

另外,一般会在 URL 参数上加上随机数(即所谓的加盐)并与 6.3 的时间戳机制组合使用以便提升防重复提交攻击。

6.5.黑名单机制

针对同一个 IP 在短时间内频繁请求的,可以通过 Nginx 进行过滤,同步可以在 Nginx 部署动态黑名单(即 IP 实时更新到黑名单库),这样可以防控少量的 DDOS。但受限于判断黑名单需要考虑多维度的信息,一般我们的 Nginx 尽量只做同一 IP 校验,更多维度的黑名单校验可以通过厂商去解决。

6.6.数据合法性校验

这里的数据合法性校验主要指的是数据格式校验和业务规则校验。

  • 数据格式校验:日期格式校验、长度校验、非空校验等;

  • 业务规则校验:如库存校验、身份证合法性校验等。

 

7、幂等性

定义:在计算机中,表示对同一个过程应用相同的参数多次和应用一次产生的效果是一样,这样的过程即被称为满足幂等性。

 

具体的解决方案有 token 机制、分布式锁、状态机等方案;这里引用一下之前看到的一篇文章,写得比较详细: https://blog.csdn.net/u011635492/article/details/81058153

 

8、接口设计的一些最佳实践

  • 即使返回的 JSON 中某字段没有值(即空值),也一定要返回该字段。同时前端也需做好这类情况的容错处理;

  • 针对单页面的多接口请求,为避免扩大攻击面,建议把多接口逻辑整合到一个接口,一个页面直接调用该接口,以避免绕过部分接口进行攻击;

  • 接口最好支持分页;分页一般有电梯式分页(即一开始算好总页数,优劣也一目了然)和游标式分页(即每次查询会拿上一页的最大的那个 ID 即 cursor 进行查询,这种方式更适合类似以时间为排序条件的互联网单页应用);

  • 针对你的接口提前做好限流;一般常用的限流有计数器、令牌桶、漏桶这三种。具体请参考接口中的几种限流实现

 

API 接口管理

 

一家公司的每个系统都会有各种各样的接口,但是大部分公司,特别是传统行业的公司的所谓接口文档更多是当每个系传统的 word 文本格式,这种传统的格式有着人尽皆知的痛点:

  1. 维护不及时;

  2. 与代码不同步;

  3. 归档后“便束之高阁”;

  4. 接口文档跟代码没有互动;

  5. 文本检索无法建立全局搜索,需要额外借助工具。

 

为了解决上述的问题,需要建立一套行之有效的接口管理体系,该体系的目标是:

  1. 能够进行接口文档管理,作为后续的接口治理的其中一部分;

  2. 能作为接口测试的平台,这样能保证接口跟代码是同步的;

  3. 支持文本检索。

 

业界有很多不同的 API 接口管理平台。如去哪儿网的 YAPI 平台、阿里某团队开发的 RAP 平台、Swagger、easyAPI。目前个人在试用 YAPI 平台,后面补充具体的教程与使用体验吧。

标签:加密,timestamp,校验,接口,sign,最佳,Token,API
From: https://www.cnblogs.com/R-bear/p/17914654.html

相关文章

  • 支持可视化提取变量,Apipost配置变量不要太简单
    在调试接口时我们需要将响应结果中的某个字段配置为环境变量在其他接口中引用,之前在Apipost中需要配置脚本而在最近Apipost后执行操作中可以进行可视化的断言和变量提取,无需配置繁琐脚本。这里我们在登录接口下配置一条Token环境变量,在后执行脚本-添加操作项-选择提取变量 输......
  • 给网站引入各大搜索引擎的关键字提示,白给的接口薅他羊毛。
    拥有一个关键词提示属于是导航网站必要的了因为网站是个导航网站,有一个搜索框,用户搜索时需要像百度一样有个搜索提示关键词列表。之前只是用百度,现在给增加了好几个,想换那个就换那个了,直接上图片可以配置属于是想选哪个选哪个,谁提示不爽就不用它,我可以用着bing的搜索引擎却使用......
  • 拼多多ID取商品详情API:电商行业的核心价值与实时数据获取策略
    一、引言在当今的电商行业中,数据是驱动业务决策和优化用户体验的关键因素。拼多多作为中国电商市场的主要参与者,其根据ID取商品详情原数据的API在电商行业中具有显著的重要性。本文将深入探讨这个话题,并介绍如何实现实时数据获取。二、拼多多根据ID取商品详情原数据API的重要性1.提......
  • vue2前端调接口下载(导出)后端返回.zip压缩文件流
    1、接口api//三级教育档案导出exportfunctionsearchPersonnelHousInfoExport(data){returnrequest({url:train+'/fileExport/controller/export/personalProfile',method:'post',data:data,responseType:'blob',......
  • 构建可扩展的网校平台:在线教育系统源码设计与架构最佳实践
    随着科技的不断发展,在线教育系统在教育领域扮演着越来越重要的角色。本文将深入探讨如何构建一个可扩展的网校平台,重点关注在线教育系统的源码设计和架构最佳实践。 一、引言在当前信息时代,教育已经超越了传统的教学方式,转向更加灵活和便捷的在线教育平台。构建一个可扩展的网校平......
  • 智慧安防视频监控可视化平台EasyCVR调用接口返回“Unauthorized”是什么原因?
    智慧安防视频监控可视化平台EasyCVR采用了开放式的网络结构,平台能在局域网、公网、专网等复杂的网络环境中,将场景中分散的海量网络监控设备进行统一接入与汇聚管理,并能提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集......
  • 面试遇到了接口分析和测试用例分析题,该如何下手?
    只要有软件产品的公司百分之九十以上都会做接口测试,要做接口测试的公司那是少不了接口测试工程师的,接口测试工程师相对于其他的职位又比较轻松并且容易胜任。如果你想从事接口测试的工作那就少不了对接口进行分析,同时也会对测试用例进行研究。当然要从事接口测试工作,必需得先过面......
  • 高德地图api报错 Get geolocation timeout.Get ipLocation failed.
    使用了https报错Getgeolocationtimeout.GetipLocationfailed. 报错是定位超时,由于JSAPI使用的是浏览器提供的定位服务,所以定位的准确度和成功率都会对浏览器有很大的依赖。由于Chrome在国内没有提供服务,因此使用Chrome定位服务的浏览器,比如:Chrome、火狐、安卓原生WebVie......
  • 腾讯云api-python调用
    https://cloud.tencent.com/document/product/1278/46716#-*-coding:utf-8-*-importhashlib,hmac,json,os,sys,timefromdatetimeimportdatetime#密钥参数#需要设置环境变量TENCENTCLOUD_SECRET_ID,值为示例的AKIDz8krbsJ5yK**********mLPx3EXAMPLEsecret_......
  • drf( Restful规范——序列化与反序列化——DjangoRESTframewordk用法——原生与drf实
    #Restful规范(重要-概念)```python#API接口---》后端要提供api接口---》2000年RoyFielding的博士论文中###restful是什么?REST全称是RepresentationalStateTransfer,表征性状态转移WebAPI接口的设计风格,尤其适用于前后端分离的应用模式中#有哪些规范10条 1数据的安全......