NOTE
3.7 如何设计开放API接口
1. 什么是开放接口 一般的API只对内部系统开放 而开放API则是对外部系统开放,其他系统或者软件可以调用这个API获取本系统的数据 2. 如何设计开放接口 2.1. 安全问题 对于开放接口,主要面临3个安全问题: - 请求身份是否可信任--认证 - 请求的参数是否被篡改--签名 - 请求是否唯一
这是历史学习笔记,可能存在过时或不完整的理解。
1. 什么是开放接口
一般的API只对内部系统开放 而开放API则是对外部系统开放,其他系统或者软件可以调用这个API获取本系统的数据
2. 如何设计开放接口
2.1. 安全问题
对于开放接口,主要面临3个安全问题:
- 请求身份是否可信任–认证
- 请求的参数是否被篡改–签名
- 请求是否唯一–防止重放攻击
2.1.1. 认证
- 用于解决身份信任问题
- 线下下发appid+secret给第三方
- 通过appid+secret换取token,之后接口请求通过token认证
- 使用token的原因在于让用户暴露的明文密码次数越少越好
2.1.2. 签名
- 用于防止参数篡改
- 过程
- 对于sign之外的所有参数按照参数名升序排序
- 排序后的参数列表组合成
key1=value1&key2=value2…的字符串, - MD5计算sign
2.1.3. 防止重放攻击
- timestamp+nonce
- timestamp一般表示参数在15分钟内有效
- nonce指唯一的随机字符串,用来标识每个被签名的请求。通过为每个请求提供一个唯一的标识符,服务器能够防止请求被多次使用
- 为了防止这两个参数被篡改需要加入参数签名
- 也可以只用nonce+redis expire
2.2. 限流
- 计数器
- 漏桶
- 令牌桶
2.3. IP白名单
- 对接入方的IP使用白名单进行控制
3. 例子
3.1. 第三方身份核验流程
下面只保留流程级伪代码,用于说明开放 API 的认证、签名、请求关联和结果查询,不对应任何具体厂商或内部系统实现。
-
发起核验
credentials = load_provider_credentials() access_token = authenticate(credentials) challenge = request_verification_challenge(access_token, subject_ref) nonce = generate_random_nonce() signature = sign(challenge, nonce, request_metadata) request_id = generate_request_id() save_request_mapping(subject_ref, request_id) verification_id = create_verification( access_token, request_id, verification_payload, signature ) -
查询核验结果
access_token = authenticate(credentials) challenge = request_query_challenge(access_token, subject_ref) nonce = generate_random_nonce() signature = sign(challenge, nonce, request_metadata) result = query_verification_result( access_token, verification_id, signature )
讨论
使用 GitHub 账号参与讨论,评论会保存在 GitHub Issues 中。在 GitHub 查看