NOTE

3.7 如何设计开放API接口

1. 什么是开放接口 一般的API只对内部系统开放 而开放API则是对外部系统开放,其他系统或者软件可以调用这个API获取本系统的数据 2. 如何设计开放接口 2.1. 安全问题 对于开放接口,主要面临3个安全问题: - 请求身份是否可信任--认证 - 请求的参数是否被篡改--签名 - 请求是否唯一

系统设计创建于 更新于 约 2 分钟读完historical

这是历史学习笔记,可能存在过时或不完整的理解。

1. 什么是开放接口

一般的API只对内部系统开放 而开放API则是对外部系统开放,其他系统或者软件可以调用这个API获取本系统的数据

2. 如何设计开放接口

2.1. 安全问题

对于开放接口,主要面临3个安全问题:

  • 请求身份是否可信任–认证
  • 请求的参数是否被篡改–签名
  • 请求是否唯一–防止重放攻击

2.1.1. 认证

  • 用于解决身份信任问题
  • 线下下发appid+secret给第三方
  • 通过appid+secret换取token,之后接口请求通过token认证
    • 使用token的原因在于让用户暴露的明文密码次数越少越好

2.1.2. 签名

  • 用于防止参数篡改
  • 过程
    1. 对于sign之外的所有参数按照参数名升序排序
    2. 排序后的参数列表组合成key1=value1&key2=value2…的字符串,
    3. MD5计算sign

2.1.3. 防止重放攻击

  • timestamp+nonce
    • timestamp一般表示参数在15分钟内有效
    • nonce指唯一的随机字符串,用来标识每个被签名的请求。通过为每个请求提供一个唯一的标识符,服务器能够防止请求被多次使用
    • 为了防止这两个参数被篡改需要加入参数签名
  • 也可以只用nonce+redis expire

2.2. 限流

  • 计数器
  • 漏桶
  • 令牌桶

如何设计一个限流系统.md

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
    )

4. 参考

讨论

使用 GitHub 账号参与讨论,评论会保存在 GitHub Issues 中。在 GitHub 查看