增加usersig

This commit is contained in:
a158
2026-03-16 17:50:45 +08:00
parent 4d7f763cfa
commit e93572f001
5 changed files with 183 additions and 2 deletions

View File

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

View File

@@ -12,6 +12,7 @@
#include <iostream>
#include <string>
#include <vector>
#include "usersig.h"
using namespace TencentCloud;
using namespace TencentCloud::Trtc::V20190722;
using namespace TencentCloud::Trtc::V20190722::Model;
@@ -72,11 +73,18 @@ std::pair<bool,std::string> module::tencent_sdk_trtc::dismissRoomByStrRoomId(con
// 输出json格式的字符串回包
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)
{
lua->new_usertype<module::tencent_sdk_trtc>("fw_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
);
}

View File

@@ -24,6 +24,22 @@ namespace module
long long sdkappid,
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:
virtual void regist_global(const char* name, sol::state* lua);
virtual void delete_global() { delete this; }

134
src/usersig.cpp Normal file
View File

@@ -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
src/usersig.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <string>
#include <cstdint>
// 生成 TRTC UserSigTLS-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);