generate_user_sig.lua 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. --[[
  2. * Module: GenerateUserSig (Lua version)
  3. * Function: Generate UserSig for Tencent Cloud IM/Board SDK
  4. * Reference: C++ implementation provided
  5. * Note: This implementation uses Lua's standard libraries and assumes the presence of 'openssl' and 'zlib' Lua modules.
  6. * Usage: require this module and call gen_user_sig(user_id, sdkappid, secretkey, expiretime)
  7. --]]
  8. require("app.app")
  9. local zlib = require("zlib")
  10. local base64 = require("app.module.base64")
  11. local M = {}
  12. -- Helper: base64 encode, then replace +, /, = as required by Tencent
  13. local function base64_url_encode(data)
  14. local b64 = base64.encode(data)
  15. -- 按照C++代码的字符替换规则
  16. b64 = b64:gsub("+", "*"):gsub("/", "-"):gsub("=", "_")
  17. return b64
  18. end
  19. -- Helper: HMAC-SHA256
  20. local function hmac_sha256(key, msg)
  21. -- 确保参数都是字符串类型
  22. return codec.hmac_sha256(tostring(key), tostring(msg))
  23. end
  24. -- Helper: hex string -> binary string
  25. local function hex_to_bin(hex)
  26. return (hex:gsub("..", function(cc)
  27. return string.char(tonumber(cc, 16))
  28. end))
  29. end
  30. -- Helper: Generate the HMAC-SHA256 signature string
  31. local function gen_hmac_sig(user_id, sdkappid, curr_time, expire_time, secret_key)
  32. local content = string.format(
  33. "TLS.identifier:%s\nTLS.sdkappid:%d\nTLS.time:%d\nTLS.expire:%d\n",
  34. user_id, sdkappid, curr_time, expire_time
  35. )
  36. -- 底层返回十六进制摘要,需转为二进制再做标准Base64
  37. local sig_hex = hmac_sha256(secret_key, content)
  38. local sig_bin = hex_to_bin(sig_hex)
  39. return base64.encode(sig_bin)
  40. end
  41. -- Main: Generate the UserSig JSON, compress, and base64 encode
  42. local function gen_user_sig(user_id, sdkappid, secretkey, expiretime)
  43. assert(user_id and user_id ~= "", "user_id must not be empty")
  44. assert(tonumber(sdkappid) and tonumber(sdkappid) > 0, "sdkappid must be a positive integer")
  45. assert(tonumber(expiretime) and tonumber(expiretime) > 0, "expiretime must be a positive integer")
  46. assert(secretkey and secretkey ~= "", "secretkey must not be empty")
  47. local curr_time = os.time()
  48. -- 按官方JS示例:TLS.expire 使用持续时间(秒),不是绝对时间戳
  49. local expire_time = expiretime
  50. local sig = gen_hmac_sig(user_id, sdkappid, curr_time, expire_time, secretkey)
  51. -- Compose JSON string (严格按照C++代码的格式和顺序)
  52. local json = string.format(
  53. '{"TLS.ver":"2.0","TLS.identifier":"%s","TLS.sdkappid":%d,"TLS.expire":%d,"TLS.time":%d,"TLS.sig":"%s"}',
  54. user_id, sdkappid, expire_time, curr_time, sig
  55. )
  56. -- Compress with zlib (raw deflate) - 使用Z_BEST_SPEED压缩级别
  57. local deflater = zlib.deflate()
  58. local compressed, eof, bytes_in, bytes_out = deflater(json, "finish")
  59. -- Base64 encode and replace chars as required
  60. local user_sig = base64_url_encode(compressed)
  61. return user_sig
  62. end
  63. -- Public API
  64. M.gen_user_sig = gen_user_sig
  65. return M