参数 | 类型 | 必须 | 说明 |
appkey | string | 是 | 根据各接口文档提供的方式获取到的 appkey。 |
timestamp | string | 是 | 请求时间戳,单位:秒。时间戳需要和当前时间的差异不过能超过五分钟,否则会鉴权失败。 |
requestid | string | 否 | 只有部分接口(如交互数智人的创建长链接通道)需要该参数。获取方式请参考对应接口文档。 |
signature | string | 是 |
appkey = example_appkeyaccesstoken = example_accesstoken域名路由 = https://api.example.com/v2/ivh/example_uri
appkey=example_appkey×tamp=1717639699
hashBytes = HmacSha256("appkey=example_appkey×tamp=1717639699","example_accesstoken")signature = Base64Encode(hashBytes)
aCNWYzZdplxWVo+JsqzZc9+J9XrwWWITfX3eQpsLVno=
https://api.example.com/v2/ivh/example_uri?appkey=example_appkey×tamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3D
package mainimport ("crypto/hmac""crypto/sha256""encoding/base64""fmt""net/url""sort""strconv""time")func GenSignature(signingContent string, accessToken string) string {// 计算 HMAC-SHA256 值h := hmac.New(sha256.New, []byte(accessToken))h.Write([]byte(signingContent))// 将 HMAC-SHA256 值进行 Base64 编码hashInBase64 := base64.StdEncoding.EncodeToString(h.Sum(nil))// URL encodeencodeSign := url.QueryEscape(hashInBase64)// 拼接签名signature := "&signature=" + encodeSignreturn signature}func GenReqURL(parameter map[string]string, accessToken string, baseURL string) string {// 按字典序拼接待计算签名的字符串signingContent := ""pathKey := make([]string, 0, len(parameter))for k := range parameter {pathKey = append(pathKey, k)}sort.Strings(pathKey)for _, k := range pathKey {if signingContent != "" {signingContent += "&"}signingContent += k + "=" + parameter[k]}// 计算签名signature := GenSignature(signingContent, accessToken)// 拼接访问接口的完整URLreturn baseURL + "?" + signingContent + signature}func main() {baseUrl := "https://api.example.com/v2/ivh/example_uri"accesstoken := "example_accesstoken"wssUrl := "wss://api.example.com/v2/ws/ivh/example_uri"// 示例一(访问需要提供 appkey 和 timestamp 参数的接口):// 用户按需填入生成签名所需的公共参数parameter := map[string]string{"appkey": "example_appkey",// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟// 示例时间戳:// "timestamp": "1717639699",// 推荐使用下面的语句生成当前时间戳:"timestamp": strconv.FormatInt(time.Now().Unix(), 10),}url1 := GenReqURL(parameter, accesstoken, baseUrl)// 使用示例时间戳输出应当如下:// Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey×tamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3Dfmt.Println("Example 1:" + url1)// 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口):// 用户按需填入生成签名所需的公共参数parameter = map[string]string{"appkey": "example_appkey","requestid": "example_requestid",// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟// 示例时间戳:// "timestamp": "1717639699",// 用户若自己提供时间戳应保证单位为秒且与当前时间相差不得超过五分钟"timestamp": strconv.FormatInt(time.Now().Unix(), 10),}url2 := GenReqURL(parameter, accesstoken, wssUrl)// 使用示例时间戳输出应当如下:// Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid×tamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3Dfmt.Println("Example 2:" + url2)}
import java.util.*;import java.util.stream.Collectors;import java.time.Instant;import java.net.URLEncoder;import java.nio.charset.StandardCharsets;import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.util.Base64;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.io.UnsupportedEncodingException;public class Presigned {public static String GenSignature(String signingContent, String accessToken) {try {// 计算 HMAC-SHA256 值Mac sha256_HMAC = Mac.getInstance("HmacSHA256");SecretKeySpec secret_key = new SecretKeySpec(accessToken.getBytes(StandardCharsets.UTF_8), "HmacSHA256");sha256_HMAC.init(secret_key);String hashInBase64 = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(signingContent.getBytes(StandardCharsets.UTF_8)));// URL encodeString encodeSign = URLEncoder.encode(hashInBase64, StandardCharsets.UTF_8.toString());// 拼接签名String signature = "&signature=" + encodeSign;return signature;} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {e.printStackTrace();return null;}}public static String GenReqURL(Map<String, String> parameter, String accessToken, String baseURL) {// 按字典序拼接待计算签名的字符串String signingContent = parameter.entrySet().stream().sorted(Map.Entry.comparingByKey()).map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining("&"));// 计算签名String signature = GenSignature(signingContent, accessToken);// 拼接访问接口的完整URLreturn baseURL + "?" + signingContent + signature;}public static void main(String[] args) {String baseUrl = "https://api.example.com/v2/ivh/example_uri";String accesstoken = "example_accesstoken";String wssUrl = "wss://api.example.com/v2/ws/ivh/example_uri";// 示例一(访问需要提供 appkey 和 timestamp 参数的接口):// 用户按需填入生成签名所需的公共参数Map<String, String> parameter = new TreeMap<>();parameter.put("appkey", "example_appkey");// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟// 示例时间戳:// parameter.put("timestamp", "1717639699");// 推荐使用下面的语句生成当前时间戳:parameter.put("timestamp", String.valueOf(Instant.now().getEpochSecond()));String url = GenReqURL(parameter, accesstoken, baseUrl);// 使用示例时间戳输出应当如下:// Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey×tamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3DSystem.out.println("Example 1:" + url);// 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口):parameter.clear();parameter.put("appkey", "example_appkey");parameter.put("requestid", "example_requestid");// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟// 示例时间戳:// parameter.put("timestamp", "1717639699");// 推荐使用下面的语句生成当前时间戳:parameter.put("timestamp", String.valueOf(Instant.now().getEpochSecond()));url = GenReqURL(parameter, accesstoken, wssUrl);// 使用示例时间戳输出应当如下:// Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid×tamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3DSystem.out.println("Example 2:" + url);}}
#include<iostream>#include <map>#include<string>#include<vector>#include<algorithm>#include <ctime>#include <iomanip>#include <sstream>#include<openssl/hmac.h>#include<openssl/sha.h>using namespace std;static const string base64_chars ="ABCDEFGHIJKLMNOPQRSTUVWXYZ""abcdefghijklmnopqrstuvwxyz""0123456789+/";string url_encode(const string &value) {ostringstream escaped;escaped.fill('0');escaped<< hex;for (size_t i = 0; i< value.length(); ++i) {char c = value[i];if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {escaped << c;} else {escaped<< uppercase;escaped << '%'<< setw(2)<< int((unsigned char) c);escaped<< nouppercase;}}return escaped.str();}string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {string ret;int i = 0;int j = 0;unsigned char char_array_3[3];unsigned char char_array_4[4];while (in_len--) {char_array_3[i++] = *(bytes_to_encode++);if (i == 3) {char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);char_array_4[3] = char_array_3[2] & 0x3f;for(i = 0; (i <4) ; i++)ret += base64_chars[char_array_4[i]];i = 0;}}if (i){for(j = i; j < 3; j++)char_array_3[j] = '\\0';char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);char_array_4[3] = char_array_3[2] & 0x3f;for (j = 0; (j < i + 1); j++)ret += base64_chars[char_array_4[j]];while((i++ < 3))ret += '=';}return ret;}string GenSignature(const string& signingContent, const string& accessToken) {// 计算 HMAC-SHA256 值unsigned char hash[EVP_MAX_MD_SIZE];unsigned int hashLength;HMAC(EVP_sha256(), accessToken.c_str(), accessToken.length(), (unsigned char *) signingContent.c_str(), signingContent.length(), hash, &hashLength);// 将 HMAC-SHA256 值进行 Base64 编码string hashInBase64 = base64_encode(hash, hashLength);// URL encodestring encodeSign = url_encode(hashInBase64);// 拼接签名string signature = "&signature=" + encodeSign;return signature;}string GenReqURL(const map<string, string>& parameter, const string& accessToken, const string& baseURL) {// 按字典序拼接待计算签名的字符串string signingContent;vector<string> pathKey;for (const auto& p : parameter) {pathKey.push_back(p.first);}sort(pathKey.begin(), pathKey.end());for (const auto& k : pathKey) {if (!signingContent.empty()) {signingContent += "&";}signingContent += k + "=" + parameter.at(k);}// 计算签名string signature = GenSignature(signingContent, accessToken);// 拼接访问接口的完整URLreturn baseURL + "?" + signingContent + signature;}// 编译时需要链接到OpenSSL库, 可以使用下面的命令:// g++ presigned.cpp -o presigned -lcryptoint main() {string baseUrl = "https://api.example.com/v2/ivh/example_uri";string accesstoken = "example_accesstoken";string wssUrl = "wss://api.example.com/v2/ws/ivh/example_uri";// 示例一(访问需要提供 appkey 和 timestamp 参数的接口):// 用户按需填入生成签名所需的公共参数map<string, string> parameter1 = {{"appkey", "example_appkey"},// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟// 示例时间戳:// {"timestamp" , "1717639699"},// 推荐使用下面的语句生成当前时间戳:{"timestamp", to_string(time(NULL))}};string url = GenReqURL(parameter1, accesstoken, baseUrl);// 使用示例时间戳输出应当如下:// Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey×tamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3Dcout << "Example 1:"<< url<< endl;// 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口):// 用户按需填入生成签名所需的公共参数map<string, string> parameter2 = {{"appkey", "example_appkey"},{"requestid", "example_requestid"},// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟// 示例时间戳:// {"timestamp" , "1717639699"},// 推荐使用下面的语句生成当前时间戳:{"timestamp", to_string(time(NULL))}};url = GenReqURL(parameter2, accesstoken, wssUrl);// 使用示例时间戳输出应当如下:// Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid×tamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3Dcout << "Example 2:"<< url<< endl;return 0;}
import hmacimport hashlibimport timeimport base64from urllib.parse import quote# 用户可以在函数内部生成时间戳, 只需要传入appkey和accessToken即可获取访问接口所需的公共参数和签名def GenSignature(signing_content, access_token):# 计算 HMAC-SHA256 值h = hmac.new(access_token.encode(), signing_content.encode(), hashlib.sha256)# 将 HMAC-SHA256 值进行 Base64 编码hash_in_base64 = base64.b64encode(h.digest()).decode()# URL encodeencode_sign = quote(hash_in_base64)# 拼接签名signature = f"&signature={encode_sign}"return signaturedef GenReqURL(parameter, access_token, base_url):# 按字典序拼接待计算签名的字符串signing_content = '&'.join(f'{k}={parameter[k]}' for k in sorted(parameter.keys()))# 计算签名signature = GenSignature(signing_content, access_token)# 拼接访问接口的完整 URLreturn f'{base_url}?{signing_content}{signature}'def main():base_url = 'https://api.example.com/v2/ivh/example_uri'access_token = 'example_accesstoken'wss_url = 'wss://api.example.com/v2/ws/ivh/example_uri'# 示例一(访问需要提供 appkey 和 timestamp 参数的接口):# 用户按需填入生成签名所需的公共参数parameter1 = {'appkey': 'example_appkey',# 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟# 示例时间戳:# 'timestamp': '1717639699'# 推荐使用下面的语句生成当前时间戳:'timestamp': int(time.time()) # 使用当前时间戳(单位:秒)}url1 = GenReqURL(parameter1, access_token, base_url)# 使用示例时间戳输出应当如下:# Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey×tamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3Dprint('Example 1:', url1)# 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口):# 用户按需填入生成签名所需的公共参数parameter2 = {'appkey': 'example_appkey','requestid': 'example_requestid',# 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟# 示例时间戳:# 'timestamp': '1717639699'# 推荐使用下面的语句生成当前时间戳:'timestamp': int(time.time()) # 使用当前时间戳(单位:秒)}url2 = GenReqURL(parameter2, access_token, wss_url)# 使用示例时间戳输出应当如下:# Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid×tamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3Dprint('Example 2:', url2)if __name__ == '__main__':main()
const crypto = require('crypto');// 用户可以在函数内部生成时间戳, 只需要传入appkey和accessToken即可获取访问接口所需的公共参数和签名function GenSignature(signingContent, accessToken) {// 计算 HMAC-SHA256 值const hmac = crypto.createHmac('sha256', accessToken);hmac.update(signingContent);// 将 HMAC-SHA256 值进行 Base64 编码const hashInBase64 = hmac.digest('base64');// URL encodeconst encodeSign = encodeURIComponent(hashInBase64);// 拼接签名const signature = `&signature=${encodeSign}`;return signature;}function GenReqURL(parameter, accessToken, baseURL) {// 按字典序拼接待计算签名的字符串let signingContent = '';const pathKey = Object.keys(parameter).sort();for (const k of pathKey) {if (signingContent !== '') {signingContent += '&';}signingContent += `${k}=${parameter[k]}`;}// 计算签名const signature = GenSignature(signingContent, accessToken);// 拼接访问接口的完整URLreturn `${baseURL}?${signingContent}${signature}`;}function main() {const baseUrl = 'https://api.example.com/v2/ivh/example_uri';const accesstoken = 'example_accesstoken';const wssUrl = 'wss://api.example.com/v2/ws/ivh/example_uri';// 示例一(访问需要提供 appkey 和 timestamp 参数的接口):// 用户按需填入生成签名所需的公共参数const parameter1 = {appkey: 'example_appkey',// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟// 示例时间戳:// timestamp: '1717639699',// 推荐使用下面的语句生成当前时间戳:timestamp: Math.floor(Date.now() / 1000), // 使用当前时间戳(单位:秒)};const url1 = GenReqURL(parameter1, accesstoken, baseUrl);// 使用示例时间戳输出应当如下:// Example 1:https://api.example.com/v2/ivh/example_uri?appkey=example_appkey×tamp=1717639699&signature=aCNWYzZdplxWVo%2BJsqzZc9%2BJ9XrwWWITfX3eQpsLVno%3Dconsole.log('Example 1:', url1);// 示例二(访问需要提供 appkey, requestID 和 timestamp 参数的接口):const parameter2 = {appkey: 'example_appkey',requestid: 'example_requestid',// 用户提供的时间戳应保证单位为秒且与当前时间相差不得超过五分钟// 示例时间戳:// timestamp: '1717639699',// 推荐使用下面的语句生成当前时间戳:timestamp: Math.floor(Date.now() / 1000), // 使用当前时间戳(单位:秒)};const url2 = GenReqURL(parameter2, accesstoken, wssUrl);// 使用示例时间戳输出应当如下:// Example 2:wss://api.example.com/v2/ws/ivh/example_uri?appkey=example_appkey&requestid=example_requestid×tamp=1717639699&signature=QVenICk0VHtHGYZKXM6IC%2BW1CjZC1joSr%2Fx0gfKKYT4%3Dconsole.log('Example 2:', url2);}main();
本页内容是否解决了您的问题?