淘宝/京东/拼多多三方接口调用设计方案

在为第三方系统提供接口的时候,肯定要考虑接口数据的安全问题,比如数据是否被篡改数据是否已经过时数据是否可以重复提交等问题

在设计三方接口调用的方案时,需要考虑到安全性和可用性。以下是一种设计方案的概述,其中包括使用API密钥(Access Key/Secret Key)进行身份验证和设置回调地址。

设计方案概述

  1. API密钥生成:为每个三方应用生成唯一的API密钥对(AK/SK),其中AK用于标识应用,SK用于进行签名和加密。

    AK:Access Key Id,用于标示用户。
    SK:Secret Access Key,是用户用于加密认证字符串和用来验证认证字符串的密钥,其中SK必须保密。
    通过使用Access Key Id / Secret Access Key加密的方法来验证某个请求的发送者身份。

  2. 接口鉴权:在进行接口调用时,客户端需要使用AK和请求参数生成签名,并将其放入请求头或参数中以进行身份验证。

    淘宝签名和验签:淘宝SDK签名算法 (yuque.com)

  3. 回调地址设置:三方应用提供回调地址,用于接收异步通知和回调结果。

  4. 接口API设计:设计接口的URL、HTTP方法、请求参数、响应格式等细节。

权限划分

  • appID:应用的唯一标识

    用来标识你的开发者账号的, 即:用户id, 可以在数据库添加索引,方便快速查找,同一个 appId 可以对应多个 appKey+appSecret,达到权限的

  • appKey:公匙(相当于账号)

    公开的,调用服务所需要的密钥。是用户的身份认证标识,用于调用平台可用服务.,可以简单理解成是账号。

  • appSecret:私匙(相当于密码)

    签名的密钥,是跟appKey配套使用的,可以简单理解成是密码。

  • token:令牌(过期失效)

使用方法

  1. 向第三方服务器请求授权时,带上AppKey和AppSecret(需存在服务器端)

  2. 第三方服务器验证appKey和appSecret在数据库、缓存中有没有记录

  3. 如果有,生成一串唯一的字符串(token令牌),返回给服务器,服务器再返回给客户端

  4. 后续客户端每次请求都需要带上token令牌

为什么 要有appKey + appSecret 这种成对出现的机制呢,?

  • 因为要加密通常用在首次验证(类似登录场景), 用 appKey(标记要申请的权限有哪些) + appSecret(密码, 表示你真的拥有这个权限)来申请一个token, 就是我们经常用到的 accessToken(通常拥有失效时间), 后续的每次请求都需要提供accessToken 表明验证权限通过。

现在有了统一的appId,此时如果针对同一个业务要划分不同的权限,比如同一功能,某些场景需要只读权限,某些场景需要读写权限。这样提供一个appId和对应的秘钥appSecret就没办法满足需求。此时就需要根据权限进行账号分配通常使用appKey和appSecret。

  • 由于 appKey 和 appSecret 是成对出现的账号同一个 appId 可以对应多个 appKey+appSecret, 这样平台就为不同的appKey+appSecret对分配不一样的权限,

    • 可以生成两对appKey和appSecret。一个用于删除,一个用于读写,达到权限的细粒度划分。如 : appKey1 + appSecect1 只有删除权限 但是 appKey2+appSecret2 有读写权限… 这样你就可以把对应的权限 放给不同的开发者。其中权限的配置都是直接跟appKey 做关联的, appKey 也需要添加数据库索引, 方便快速查找


简化的场景:

  • 第一种场景:通常用于开放性接口,像地图api,会省去app_id和app_key,此时相当于三者相等,合而为一 appId = appKey = appSecret, 。这种模式下,带上app_id的目的仅仅是统计某一个用户调用接口的次数而已了。

  • 第二种场景: 当每一个用户有且仅有一套权限配置 可以去掉 appKey, , 直接将app_id = app_key, 每个用户分配一个appId+ appSecret就够了`.

也可以

可以采用签名(signature)的方式:当调用方向服务提供方法发起请求时,带上(appKey、时间戳timeStamp、随机数nonce、签名sign) 签名sign 可以使用 (AppSecret + 时间戳 + 随机数)使用sha1、md5生成,服务提供方收到后,生成本地签名和收到的签名比对,如果一致,校验成功

签名流程

图片

签名规则

  1. 分配appId(开发者标识)appSecret(密钥),给 不同的调用方

    可以直接通过平台线上申请,也可以线下直接颁发。appId是全局唯一的,每个appId将对应一个客户,密钥appSecret需要高度保密。

  2. 加入timeStamp(时间戳),以服务端当前时间为准,单位为ms ,5分钟内数据有效

    时间戳的目的就是为了减轻DOS攻击。防止请求被拦截后一直尝试请求接口。服务器端设置时间戳阀值,如果服务器时间 减 请求时间戳超过阀值,表示签名超时,接口调用失败。

  3. 加入临时流水号nonce至少为10位 ,有效期内防重复提交

    随机值nonce 主要是为了增加签名sign的多变性,也可以保护接口的幂等性,相邻的两次请求nonce不允许重复,如果重复则认为是重复提交,接口调用失败。

    通过在接口签名请求参数加上 时间戳timeStamp + 随机数nonce 可以防止 ”重放攻击“
    1.时间戳(timeStamp):
    以服务端当前时间为准,服务端要求客户端发过来的时间戳,必须是最近60秒内(假设值,自己定义)的。
    这样,即使这个请求即使被截取了,也只能在60s内进行重放攻击。
    2.随机数(nonce):
    但是,即使设置了时间戳,攻击者还有60s的攻击时间呢!
    所以我们需要在客户端请求中再加上一个随机数(中间黑客不可能自己修改随机数,因为有参数签名的校验呢),
    服务端会对一分钟内请求的随机数进行检查,如果有两个相同的,基本可以判定为重放攻击。
    因为正常情况下,在短时间内(比如60s)连续生成两个相同nonce的情况几乎为0

    服务端“第一次”在接收到这个nonce的时候做下面行为:
    1.去redis中查找是否有key为nonce:{ nonce}的数据
    2.如果没有,则创建这个key,把这个key失效的时间和验证timestamp失效的时间一致,比如是60s。
    3.如果有,说明这个key在60s内已经被使用了,那么这个请求就可以判断为重放请求。

    • 针对查询接口,流水号只用于日志落地,便于后期日志核查。

    • 针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求。

  4. 加入签名字段sign,获取调用方传递的签名信息。

    通过在接口签名请求参数加上 时间戳appId + sign 解决身份验证和防止 ”参数篡改“
    1.请求携带参数appId和Sign,只有拥有合法的身份appId和正确的签名Sign才能放行。这样就解决了身份验证和参数篡改问题。
    2.即使请求参数被劫持,由于获取不到appSecret(仅作本地加密使用,不参与网络传输),也无法伪造合法的请求。

以上字段放在请求头中。

API接口设计

根据你的具体需求和业务场景,以下是一个简单示例的API接口设计:

1. 获取资源列表接口

  • URL: /api/resources

  • HTTP 方法: GET

  • 请求参数:

    • page (可选): 页码

    • limit (可选): 每页限制数量

  • 响应:

    • 成功状态码: 200 OK

    • 响应体: 返回资源列表的JSON数组

2. 创建资源接口

  • URL: /api/resources

  • HTTP 方法: POST

  • 请求参数:

    • name (必填): 资源名称

    • description (可选): 资源描述

  • 响应:

    • 成功状态码: 201 Created

    • 响应体: 返回新创建资源的ID等信息

3. 更新资源接口

  • URL: /api/resources/{resourceId}

  • HTTP 方法: PUT

  • 请求参数:

    • resourceId (路径参数, 必填): 资源ID

    • name (可选): 更新后的资源名称

    • description (可选): 更新后的资源描述

  • 响应:

    • 成功状态码: 200 OK

4. 删除资源接口

  • URL: /api/resources/{resourceId}

  • HTTP 方法: DELETE

  • 请求参数:

    • resourceId (路径参数, 必填): 资源ID

  • 响应:

    • 成功状态码: 204 No Content

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值