前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >标准API接口设计规范

标准API接口设计规范

作者头像
Tinywan
发布2024-06-04 19:00:56
2370
发布2024-06-04 19:00:56
举报
文章被收录于专栏:开源技术小栈

接口签名

接口签名是一种常见的安全措施,用于确保API请求的完整性和身份验证。

实现步骤

以下是实现接口签名的一般步骤:

  1. 参数收集:首先,收集所有将发送到API的参数,包括例如用户ID、操作类型、请求数据等。
  2. 排序:为了确保签名的一致性,通常需要对参数进行字典序排序。
  3. 拼接字符串:将排序后的参数与其值拼接成一个字符串。通常还会在这个字符串中包含一个时间戳和一个密钥(Secret Key)。例如:stringToSign = method + path + params + timestamp + secretKey其中:
    • method 是HTTP请求方法,如GET或POST。
    • path 是API的路径。
    • params 是经过排序的参数字符串。
    • timestamp 是请求发起的时间戳。
    • secretKey 是只有服务器和客户端知道的密钥。
  4. 散列加密:使用一个散列函数,如MD5、SHA-1或SHA-256,对上一步生成的字符串进行加密,生成签名。例如:sign = hash(stringToSign)
  5. 发送请求:在发送API请求时,在请求参数或请求头中增加sign参数。
  6. 服务器验证:服务器接收到请求后,会用相同的方法重新生成签名,并与客户端提供的签名进行比对。如果两者一致,则认为请求是合法的。
  7. 安全考虑
    • 确保secretKey安全,不要泄露给未经授权的第三方。
    • 可以考虑使用HTTPS来加密传输过程,防止中间人攻击。
    • 签名中包含时间戳可以防止重放攻击,需要验证时间戳的有效性。
  8. 错误处理:如果签名验证失败,服务器应该返回一个错误响应,并记录可能的安全事件。接口签名机制能够有效地防止API请求被篡改,确保数据的安全性和请求的合法性。不过,它不提供加密通信的功能,因此对于敏感信息的传输,还需要结合使用加密技术。

案例

生成密钥对
代码语言:javascript
复制
$originalUuid = Uuid::uuid4()->toString();
$app_key = str_replace('-', '', $originalUuid); // 唯一标识ID uuid
$timestamp = time();
$app_secret = sha1($app_key . '|'.$timestamp); // sha1(app_key + update_time)
$createData = [
    'app_name' => '阿克苏平台',
    'app_key' => $app_key,
    'app_secret' => password_hash($app_secret, PASSWORD_DEFAULT), // 加密保存
    'create_time' => $timestamp,
    'update_time' => $timestamp
];
if(AppModel::create($createData)){
    return response_json(200, 'ok');
}
校验签名
代码语言:javascript
复制
// [1] 从请求头中获取签名
$signature = $this->request->header()['x-resty-signature'] ?? '';
// [2] 签名解析 获取: 哈希算法 和 明文数据
list($hashType, $hashValue) = explode('=', $signature, 2);
// [3] 获取请求的内容,格式为json字符换
$jsonContent = $this->request->getContent();
if(empty($jsonContent)) {
    return response_json(400, '请求内容不能为空');
}
$arrayContent = json_decode($jsonContent, true);
if(!isset($arrayContent['app_key']) || !isset($arrayContent['timestamp'])) {
    return response_json(400, '请求app_key timestamp不能为空');
}

if (($arrayContent['timestamp'] + 20) < time() ) {
    return response_json(403, 'timestamp过期');
}
$appInfo = AppModel::where('app_key',$arrayContent['app_key'])->findOrEmpty();
if($appInfo->isEmpty()) {
    return response_json(400, '无效的app_key');
}
// [4] 生成 appSecret
$appSecret = sha1($appInfo->app_key . '|'.$appInfo->update_time);
// [5] hash_hmac — 使用 HMAC 方法生成带有密钥的哈希值
$checkHash = hash_hmac($hashType, json_encode($arrayContent), $appSecret);
// [6] 签名校验
if ($checkHash != $hashValue) {
    return response_json(403, '无效的签名',$this->request->header());
}
return response_json(200, 'ok',$arrayContent);

数据加密

在设计和实现API接口时,我们经常需要处理一些敏感数据,例如用户的登录密码、银行卡号、身份证号码等。这些信息若以明文形式在网络上传输,将面临极大的安全风险,容易受到恶意监听和数据泄露的威胁。

在设计和实现API接口时,我们经常需要处理一些敏感数据,例如用户的登录密码、银行卡号、转账金额和身份证号码等。这些信息若以明文形式在网络上传输,将面临极大的安全风险,容易受到恶意监听和数据泄露的威胁。

安全建议

为了确保这些关键信息的安全,我们必须采取加密措施来保护数据的完整性和隐私性。以下是一些加强数据安全的建议:

  1. 使用HTTPS:始终通过HTTPS协议发送数据,利用SSL/TLS加密层来保护数据传输过程中的安全。
  2. 敏感数据加密:对于特别敏感的信息,如登录密码,应在客户端侧进行加密处理,确保只有授权的服务器端能够解密并访问原始数据。
  3. 散列密码存储:对于密码等验证信息,不应以明文形式存储或传输。应使用强散列函数(如bcrypt、scrypt或Argon2)来处理密码,并存储散列值。

案例

SM4算法是一种分组密码算法。其分组长度为128bit,密钥长度也为128bit。加密算法与密钥扩展算法均采用32轮非线性迭代结构,以字(32位)为单位进行加密运算,每一次迭代运算均为一轮变换函数F。SM4算法加/解密算法的结构相同,只是使用轮密钥相反,其中解密轮密钥是加密轮密钥的逆序。

SM4加密方式类似于AES加密,为对称加密,可以通过相应的秘钥进行加密和解密

加密
代码语言:javascript
复制
$key = '35d251411ea04318565f0dbda6ffb6a8';

// 加密内容
$content = [
    'name' => 'Tinywan',
    'School' => 'ZheJiang University',
    'age' => 24,
    'github' => [
        'url' => 'https://github.com/Tinywan',
        'start' => 2000,
    ],
];

// 必须转换为字符串
$content = json_encode($content, JSON_UNESCAPED_UNICODE);
$sm4 = new SM4($key);
$encryptContent = $sm4->encrypt($content);
var_dump($encryptContent);
// 加密内容:b4358f5860343dbf2089ba75ee55deca8d922a069413f39cb3f8b64c01048c780ba5f03290642505d65d79c59684d76cf42443047f547c9f29dc2a49f872a2719ce00539058ab1fb5830e8e0c10144b574a87118390baa765b3429ba7afe5d28
解密
代码语言:javascript
复制
$key = '35d251411ea04318565f0dbda6ffb6a8';

// 加密内容
$encryptContent = 'b4358f5860343dbf2089ba75ee55deca8d922a069413f39cb3f8b64c01048c780ba5f03290642505d65d79c59684d76cf42443047f547c9f29dc2a49f872a2719ce00539058ab1fb5830e8e0c10144b574a87118390baa765b3429ba7afe5d28';

$sm4 = new SM4($key);
$decryptedJsonContent = $sm4->decrypt($encryptContent);
print_r($decryptedJsonContent);

解密结果

代码语言:javascript
复制
{
    "name": "Tinywan",
    "School": "ZheJiang University",
    "age": 24,
    "github": {
        "url": "https://github.com/Tinywan",
        "start": 2021
    }
}

可以通过 json_decode($decryptedJsonContent, true) ,转换为数组使用

响应格式统一

API接口响应格式的统一对于客户端开发者来说非常重要,它有助于提高开发效率、降低出错率,并能够快速集成和调试接口。

格式建议

以下是一些建议,用于确保API响应格式的统一性:

  1. 明确的版本号:在响应中包含API版本号,这样在API更新时可以保持向后兼容性。
  2. 统一的状态码:使用标准HTTP状态码来表示请求的结果,如200表示成功,400表示客户端错误,500表示服务器错误等。
  3. 数据封装:响应的数据应该被封装在一个统一的字段中,例如data,这样可以在不同的响应中保持一致性。
  4. 分页信息:如果响应数据支持分页,应提供统一的分页信息,如total(总记录数)、perPage(每页记录数)、currentPage(当前页码)和totalPages(总页数)。

通过以上措施,可以确保API接口的响应格式统一、清晰,并且易于客户端开发者使用和集成。

案例

成功示例

代码语言:javascript
复制
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "code": 0,
    "msg": "success",
    "data": {
        "token_type": "Bearer",
        "expires_in": 7200,
        "access_token": "XXXXXXXXXXX"
    }
}

异常实例

代码语言:javascript
复制
HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
    "code": 0,
    "msg": "应用信息不存在",
    "data": {}
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接口签名
    • 实现步骤
      • 案例
        • 生成密钥对
        • 校验签名
    • 数据加密
      • 安全建议
        • 案例
          • 加密
          • 解密
      • 响应格式统一
        • 格式建议
          • 案例
          相关产品与服务
          云服务器
          云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档