Browse Source

增加usersig

a158 6 months ago
parent
commit
e93572f001
5 changed files with 183 additions and 2 deletions
  1. 2 1
      CMakeLists.txt
  2. 9 1
      src/tencent_sdk_trtc.cpp
  3. 16 0
      src/tencent_sdk_trtc.h
  4. 134 0
      src/usersig.cpp
  5. 22 0
      src/usersig.h

+ 2 - 1
CMakeLists.txt

@@ -31,7 +31,8 @@ foreach(header IN LISTS HEADER_FILES)
 endforeach()
 endforeach()
 
 
 set(CMAKE_CXX_STANDARD 20) 
 set(CMAKE_CXX_STANDARD 20) 
-set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
 # 安装复制
 # 安装复制
 set(CMAKE_INSTALL_ALWAYS_COPY TRUE)
 set(CMAKE_INSTALL_ALWAYS_COPY TRUE)
 
 

+ 9 - 1
src/tencent_sdk_trtc.cpp

@@ -12,6 +12,7 @@
 #include <iostream>
 #include <iostream>
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
+#include "usersig.h"
 using namespace TencentCloud;
 using namespace TencentCloud;
 using namespace TencentCloud::Trtc::V20190722;
 using namespace TencentCloud::Trtc::V20190722;
 using namespace TencentCloud::Trtc::V20190722::Model;
 using namespace TencentCloud::Trtc::V20190722::Model;
@@ -72,11 +73,18 @@ std::pair<bool,std::string> module::tencent_sdk_trtc::dismissRoomByStrRoomId(con
     // 输出json格式的字符串回包
     // 输出json格式的字符串回包
     return std::make_pair(true, resp.ToJsonString());
     return std::make_pair(true, resp.ToJsonString());
 }
 }
+
+std::string module::tencent_sdk_trtc::getUserSig(long long sdkappid,const std::string& secret_key,const std::string& user_id,int expire_time)
+{
+    std::string sig = GenerateUserSig(user_id, sdkappid, secret_key, expire_time);
+    return sig;
+}
 void module::tencent_sdk_trtc::regist(sol::state* lua)
 void module::tencent_sdk_trtc::regist(sol::state* lua)
 {
 {
     lua->new_usertype<module::tencent_sdk_trtc>("fw_tencent_sdk_trtc",
     lua->new_usertype<module::tencent_sdk_trtc>("fw_tencent_sdk_trtc",
         "new", sol::constructors<module::tencent_sdk_trtc()>(),
         "new", sol::constructors<module::tencent_sdk_trtc()>(),
-        "dismissRoomByStrRoomId", &module::tencent_sdk_trtc::dismissRoomByStrRoomId
+        "dismissRoomByStrRoomId", &module::tencent_sdk_trtc::dismissRoomByStrRoomId,
+        "getUserSig", &module::tencent_sdk_trtc::getUserSig
     );
     );
 }
 }
 
 

+ 16 - 0
src/tencent_sdk_trtc.h

@@ -24,6 +24,22 @@ namespace module
 			long long sdkappid,
 			long long sdkappid,
 			const std::string& room_id
 			const std::string& room_id
 		);
 		);
+		
+
+		/**
+		 * @brief 获取用户签名
+		 * @param sdkappid SDKAPPID
+		 * @param secret_key 密钥
+		 * @param user_id 用户ID
+		 * @param expire_time 过期时间
+		 * @return 用户签名
+		 */
+		std::string getUserSig(
+			long long sdkappid,
+			const std::string& secret_key,
+			const std::string& user_id,
+			int expire_time
+		);
 	private:
 	private:
 		virtual void regist_global(const char* name, sol::state* lua);
 		virtual void regist_global(const char* name, sol::state* lua);
 		virtual void delete_global() { delete this; }
 		virtual void delete_global() { delete this; }

+ 134 - 0
src/usersig.cpp

@@ -0,0 +1,134 @@
+#include "usersig.h"
+
+#include <stdexcept>
+#include <ctime>
+#include <vector>
+#include <sstream>
+
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <zlib.h>
+
+
+// 简单的 Base64 实现
+const std::string BASE64_CHARS =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "abcdefghijklmnopqrstuvwxyz"
+    "0123456789+/";
+
+std::string base64Encode(const unsigned char* data, size_t len) {
+    std::string ret;
+    ret.reserve(((len + 2) / 3) * 4);
+
+    unsigned int val = 0;
+    int valb = -6;
+    for (size_t i = 0; i < len; ++i) {
+        val = (val << 8) + data[i];
+        valb += 8;
+        while (valb >= 0) {
+            ret.push_back(BASE64_CHARS[(val >> valb) & 0x3F]);
+            valb -= 6;
+        }
+    }
+    if (valb > -6) {
+        ret.push_back(BASE64_CHARS[((val << 8) >> (valb + 8)) & 0x3F]);
+    }
+    while (ret.size() % 4) {
+        ret.push_back('=');
+    }
+    return ret;
+}
+
+// '+' -> '*', '/' -> '-', '=' -> '_'
+std::string base64ToUrlSafe(std::string s) {
+    for (char& c : s) {
+        if (c == '+') c = '*';
+        else if (c == '/') c = '-';
+        else if (c == '=') c = '_';
+    }
+    return s;
+}
+
+// 使用 OpenSSL 计算 HMAC-SHA256
+std::string hmacSHA256(const std::string& key, const std::string& msg) {
+    unsigned char md[EVP_MAX_MD_SIZE];
+    unsigned int md_len = 0;
+
+    if (!HMAC(EVP_sha256(),
+              key.data(), static_cast<int>(key.size()),
+              reinterpret_cast<const unsigned char*>(msg.data()),
+              msg.size(),
+              md, &md_len)) {
+        throw std::runtime_error("HMAC(EVP_sha256) 计算失败");
+    }
+
+    return std::string(reinterpret_cast<char*>(md), md_len);
+}
+
+// 使用 zlib 压缩
+std::string zlibCompress(const std::string& input) {
+    if (input.empty()) return std::string();
+
+    uLong srcLen = static_cast<uLong>(input.size());
+    uLong destLen = compressBound(srcLen);
+    std::vector<Bytef> out(destLen);
+
+    int ret = compress2(out.data(), &destLen,
+                        reinterpret_cast<const Bytef*>(input.data()),
+                        srcLen, Z_BEST_SPEED);
+    if (ret != Z_OK) {
+        throw std::runtime_error("zlib compress2 失败, ret = " + std::to_string(ret));
+    }
+
+    return std::string(reinterpret_cast<char*>(out.data()), destLen);
+}
+
+
+std::string GenerateUserSig(const std::string& user_id,
+                            int sdk_app_id,
+                            const std::string& secret_key,
+                            std::uint32_t expire) {
+    if (sdk_app_id <= 0) {
+        throw std::invalid_argument("sdk_app_id 无效");
+    }
+    if (secret_key.empty()) {
+        throw std::invalid_argument("secret_key 不能为空");
+    }
+
+    std::uint32_t curr_time = static_cast<std::uint32_t>(std::time(nullptr));
+
+    // 1. 生成需要 HMAC 的原始字符串
+    std::ostringstream ss;
+    ss << "TLS.identifier:" << user_id << "\n"
+       << "TLS.sdkappid:" << sdk_app_id << "\n"
+       << "TLS.time:" << curr_time << "\n"
+       << "TLS.expire:" << expire << "\n";
+    std::string content_to_sign = ss.str();
+
+    // 2. 计算 HMAC-SHA256 并做标准 Base64
+    std::string hmac_res = hmacSHA256(secret_key, content_to_sign);
+    std::string sig = base64Encode(
+        reinterpret_cast<const unsigned char*>(hmac_res.data()),
+        hmac_res.size());
+
+    // 3. 拼接 JSON
+    std::ostringstream json;
+    json << "{"
+         << "\"TLS.ver\":\"2.0\","
+         << "\"TLS.identifier\":\"" << user_id << "\","
+         << "\"TLS.sdkappid\":" << sdk_app_id << ","
+         << "\"TLS.expire\":" << expire << ","
+         << "\"TLS.time\":" << curr_time << ","
+         << "\"TLS.sig\":\"" << sig << "\""
+         << "}";
+    std::string json_str = json.str();
+
+    // 4. 压缩 + Base64 + URL 安全替换
+    std::string compressed = zlibCompress(json_str);
+    std::string b64 = base64Encode(
+        reinterpret_cast<const unsigned char*>(compressed.data()),
+        compressed.size());
+    std::string url_safe = base64ToUrlSafe(b64);
+
+    return url_safe;
+}

+ 22 - 0
src/usersig.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+#include <cstdint>
+
+// 生成 TRTC UserSig(TLS-SigAPIv2)
+// 参数:
+// - user_id     : 用户 ID,对应 TLS.identifier
+// - sdk_app_id  : 控制台创建的 TRTC 应用 SDKAppID
+// - secret_key  : 控制台获取的密钥 SecretKey
+// - expire      : 过期时间(秒),例如 7 * 24 * 60 * 60
+//
+// 返回:
+// - 用于 TRTC 鉴权的 UserSig 字符串
+//
+// 说明:
+// - 该函数仅做算法封装,不做任何网络/IO 操作
+// - 推荐在服务端调用本函数生成 UserSig,再下发到客户端
+std::string GenerateUserSig(const std::string& user_id,
+                            int sdk_app_id,
+                            const std::string& secret_key,
+                            std::uint32_t expire);