-
Notifications
You must be signed in to change notification settings - Fork 60.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
146 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
"use server"; | ||
import * as crypto from "node:crypto"; | ||
// 使用 SHA-256 和 secret 进行 HMAC 加密 | ||
function sha256(message: any, secret = "", encoding?: string) { | ||
return crypto | ||
.createHmac("sha256", secret) | ||
.update(message) | ||
.digest(encoding as any); | ||
} | ||
|
||
// 使用 SHA-256 进行哈希 | ||
function getHash(message: any, encoding = "hex") { | ||
return crypto | ||
.createHash("sha256") | ||
.update(message) | ||
.digest(encoding as any); | ||
} | ||
|
||
function getDate(timestamp: number) { | ||
const date = new Date(timestamp * 1000); | ||
const year = date.getUTCFullYear(); | ||
const month = ("0" + (date.getUTCMonth() + 1)).slice(-2); | ||
const day = ("0" + date.getUTCDate()).slice(-2); | ||
return `${year}-${month}-${day}`; | ||
} | ||
|
||
export async function getHeader( | ||
payload: any, | ||
SECRET_ID: string, | ||
SECRET_KEY: string, | ||
) { | ||
// https://cloud.tencent.com/document/api/1729/105701 | ||
|
||
const endpoint = "hunyuan.tencentcloudapi.com"; | ||
const service = "hunyuan"; | ||
const region = ""; // optional | ||
const action = "ChatCompletions"; | ||
const version = "2023-09-01"; | ||
const timestamp = Math.floor(Date.now() / 1000); | ||
//时间处理, 获取世界时间日期 | ||
const date = getDate(timestamp); | ||
|
||
// ************* 步骤 1:拼接规范请求串 ************* | ||
|
||
const hashedRequestPayload = getHash(payload); | ||
const httpRequestMethod = "POST"; | ||
const contentType = "application/json"; | ||
const canonicalUri = "/"; | ||
const canonicalQueryString = ""; | ||
const canonicalHeaders = | ||
`content-type:${contentType}\n` + | ||
"host:" + | ||
endpoint + | ||
"\n" + | ||
"x-tc-action:" + | ||
action.toLowerCase() + | ||
"\n"; | ||
const signedHeaders = "content-type;host;x-tc-action"; | ||
|
||
const canonicalRequest = [ | ||
httpRequestMethod, | ||
canonicalUri, | ||
canonicalQueryString, | ||
canonicalHeaders, | ||
signedHeaders, | ||
hashedRequestPayload, | ||
].join("\n"); | ||
|
||
// ************* 步骤 2:拼接待签名字符串 ************* | ||
const algorithm = "TC3-HMAC-SHA256"; | ||
const hashedCanonicalRequest = getHash(canonicalRequest); | ||
const credentialScope = date + "/" + service + "/" + "tc3_request"; | ||
const stringToSign = | ||
algorithm + | ||
"\n" + | ||
timestamp + | ||
"\n" + | ||
credentialScope + | ||
"\n" + | ||
hashedCanonicalRequest; | ||
|
||
// ************* 步骤 3:计算签名 ************* | ||
const kDate = sha256(date, "TC3" + SECRET_KEY); | ||
const kService = sha256(service, kDate); | ||
const kSigning = sha256("tc3_request", kService); | ||
const signature = sha256(stringToSign, kSigning, "hex"); | ||
|
||
// ************* 步骤 4:拼接 Authorization ************* | ||
const authorization = | ||
algorithm + | ||
" " + | ||
"Credential=" + | ||
SECRET_ID + | ||
"/" + | ||
credentialScope + | ||
", " + | ||
"SignedHeaders=" + | ||
signedHeaders + | ||
", " + | ||
"Signature=" + | ||
signature; | ||
|
||
return { | ||
Authorization: authorization, | ||
"Content-Type": contentType, | ||
Host: endpoint, | ||
"X-TC-Action": action, | ||
"X-TC-Timestamp": timestamp.toString(), | ||
"X-TC-Version": version, | ||
"X-TC-Region": region, | ||
}; | ||
} |