$app_key = str_replace('-', '', $originalUuid); // 唯一標(biāo)識(shí)ID uuid
$timestamp = time();
$app_secret = sha1($app_key . '|'.$timestamp); // sha1(app_key + update_time)
$createData = [
'app_name' => '阿克蘇平臺(tái)',
'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');
}

校驗(yàn)簽名

// [1] 從請(qǐng)求頭中獲取簽名
$signature = $this->request->header()['x-resty-signature'] ?? '';
// [2] 簽名解析 獲取: 哈希算法 和 明文數(shù)據(jù)
list($hashType, $hashValue) = explode('=', $signature, 2);
// [3] 獲取請(qǐng)求的內(nèi)容,格式為json字符換
$jsonContent = $this->request->getContent();
if(empty($jsonContent)) {
return response_json(400, '請(qǐng)求內(nèi)容不能為空');
}
$arrayContent = json_decode($jsonContent, true);
if(!isset($arrayContent['app_key']) || !isset($arrayContent['timestamp'])) {
return response_json(400, '請(qǐng)求app_key timestamp不能為空');
}

if (($arrayContent['timestamp'] + 20) < time() ) {
return response_json(403, 'timestamp過(guò)期');
}
$appInfo = AppModel::where('app_key',$arrayContent['app_key'])->findOrEmpty();
if($appInfo->isEmpty()) {
return response_json(400, '無(wú)效的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] 簽名校驗(yàn)
if ($checkHash != $hashValue) {
return response_json(403, '無(wú)效的簽名',$this->request->header());
}
return response_json(200, 'ok',$arrayContent);

數(shù)據(jù)加密

在設(shè)計(jì)和實(shí)現(xiàn)API接口時(shí),我們經(jīng)常需要處理一些敏感數(shù)據(jù),例如用戶的登錄密碼、銀行卡號(hào)、身份證號(hào)碼等。這些信息若以明文形式在網(wǎng)絡(luò)上傳輸,將面臨極大的安全風(fēng)險(xiǎn),容易受到惡意監(jiān)聽和數(shù)據(jù)泄露的威脅。

在設(shè)計(jì)和實(shí)現(xiàn)API接口時(shí),我們經(jīng)常需要處理一些敏感數(shù)據(jù),例如用戶的登錄密碼、銀行卡號(hào)、轉(zhuǎn)賬金額和身份證號(hào)碼等。這些信息若以明文形式在網(wǎng)絡(luò)上傳輸,將面臨極大的安全風(fēng)險(xiǎn),容易受到惡意監(jiān)聽和數(shù)據(jù)泄露的威脅。

安全建議

為了確保這些關(guān)鍵信息的安全,我們必須采取加密措施來(lái)保護(hù)數(shù)據(jù)的完整性和隱私性。以下是一些加強(qiáng)數(shù)據(jù)安全的建議:

  1. 使用HTTPS:始終通過(guò)HTTPS協(xié)議發(fā)送數(shù)據(jù),利用SSL/TLS加密層來(lái)保護(hù)數(shù)據(jù)傳輸過(guò)程中的安全。
  2. 敏感數(shù)據(jù)加密:對(duì)于特別敏感的信息,如登錄密碼,應(yīng)在客戶端側(cè)進(jìn)行加密處理,確保只有授權(quán)的服務(wù)器端能夠解密并訪問(wèn)原始數(shù)據(jù)。
  3. 散列密碼存儲(chǔ):對(duì)于密碼等驗(yàn)證信息,不應(yīng)以明文形式存儲(chǔ)或傳輸。應(yīng)使用強(qiáng)散列函數(shù)(如bcrypt、scrypt或Argon2)來(lái)處理密碼,并存儲(chǔ)散列值。

案例

SM4算法是一種分組密碼算法。其分組長(zhǎng)度為128bit,密鑰長(zhǎng)度也為128bit。加密算法與密鑰擴(kuò)展算法均采用32輪非線性迭代結(jié)構(gòu),以字(32位)為單位進(jìn)行加密運(yùn)算,每一次迭代運(yùn)算均為一輪變換函數(shù)F。SM4算法加/解密算法的結(jié)構(gòu)相同,只是使用輪密鑰相反,其中解密輪密鑰是加密輪密鑰的逆序。

SM4加密方式類似于AES加密,為對(duì)稱加密,可以通過(guò)相應(yīng)的秘鑰進(jìn)行加密和解密

加密

$key = '35d251411ea04318565f0dbda6ffb6a8';

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

// 必須轉(zhuǎn)換為字符串
$content = json_encode($content, JSON_UNESCAPED_UNICODE);
$sm4 = new SM4($key);
$encryptContent = $sm4->encrypt($content);
var_dump($encryptContent);
// 加密內(nèi)容:b4358f5860343dbf2089ba75ee55deca8d922a069413f39cb3f8b64c01048c780ba5f03290642505d65d79c59684d76cf42443047f547c9f29dc2a49f872a2719ce00539058ab1fb5830e8e0c10144b574a87118390baa765b3429ba7afe5d28

解密

$key = '35d251411ea04318565f0dbda6ffb6a8';

// 加密內(nèi)容
$encryptContent = 'b4358f5860343dbf2089ba75ee55deca8d922a069413f39cb3f8b64c01048c780ba5f03290642505d65d79c59684d76cf42443047f547c9f29dc2a49f872a2719ce00539058ab1fb5830e8e0c10144b574a87118390baa765b3429ba7afe5d28';

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

解密結(jié)果

{
"name": "Tinywan",
"School": "ZheJiang University",
"age": 24,
"github": {
"url": "https://github.com/Tinywan",
"start": 2021
}
}

可以通過(guò) json_decode($decryptedJsonContent, true) ,轉(zhuǎn)換為數(shù)組使用

響應(yīng)格式統(tǒng)一

API接口響應(yīng)格式的統(tǒng)一對(duì)于客戶端開發(fā)者來(lái)說(shuō)非常重要,它有助于提高開發(fā)效率、降低出錯(cuò)率,并能夠快速集成和調(diào)試接口。

格式建議

以下是一些建議,用于確保API響應(yīng)格式的統(tǒng)一性:

  1. 明確的版本號(hào):在響應(yīng)中包含API版本號(hào),這樣在API更新時(shí)可以保持向后兼容性。
  2. 統(tǒng)一的狀態(tài)碼:使用標(biāo)準(zhǔn)HTTP狀態(tài)碼來(lái)表示請(qǐng)求的結(jié)果,如200表示成功,400表示客戶端錯(cuò)誤,500表示服務(wù)器錯(cuò)誤等。
  3. 數(shù)據(jù)封裝:響應(yīng)的數(shù)據(jù)應(yīng)該被封裝在一個(gè)統(tǒng)一的字段中,例如data,這樣可以在不同的響應(yīng)中保持一致性。
  4. 分頁(yè)信息:如果響應(yīng)數(shù)據(jù)支持分頁(yè),應(yīng)提供統(tǒng)一的分頁(yè)信息,如total(總記錄數(shù))、perPage(每頁(yè)記錄數(shù))、currentPage(當(dāng)前頁(yè)碼)和totalPages(總頁(yè)數(shù))。

通過(guò)以上措施,可以確保API接口的響應(yīng)格式統(tǒng)一、清晰,并且易于客戶端開發(fā)者使用和集成。

案例

成功示例

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"
}
}

異常實(shí)例

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
"code": 0,
"msg": "應(yīng)用信息不存在",
"data": {}
}

本文章轉(zhuǎn)載微信公眾號(hào)@開源技術(shù)小棧

上一篇:

阿里研究員谷樸:API 設(shè)計(jì)最佳實(shí)踐的思考

下一篇:

最流行的 RESTful API 要怎么設(shè)計(jì)?
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)