62 lines
2.0 KiB
C#
62 lines
2.0 KiB
C#
using System.Security.Cryptography;
|
||
using System.Text;
|
||
using System.Text.Json;
|
||
|
||
namespace CampusErrand.Services;
|
||
|
||
/// <summary>
|
||
/// 腾讯 IM 服务,负责生成 UserSig
|
||
/// </summary>
|
||
public class TencentIMService
|
||
{
|
||
private readonly long _sdkAppId;
|
||
private readonly string _secretKey;
|
||
|
||
public TencentIMService(IConfiguration configuration)
|
||
{
|
||
var config = configuration.GetSection("TencentIM");
|
||
_sdkAppId = config.GetValue<long>("SDKAppId");
|
||
_secretKey = config["SecretKey"]!;
|
||
}
|
||
|
||
public long SDKAppId => _sdkAppId;
|
||
|
||
/// <summary>
|
||
/// 生成 UserSig
|
||
/// </summary>
|
||
/// <param name="userId">用户标识</param>
|
||
/// <param name="expireSeconds">有效期(秒),默认7天</param>
|
||
public string GenerateUserSig(string userId, int expireSeconds = 604800)
|
||
{
|
||
var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||
var obj = new Dictionary<string, object>
|
||
{
|
||
["TLS.ver"] = "2.0",
|
||
["TLS.identifier"] = userId,
|
||
["TLS.sdkappid"] = _sdkAppId,
|
||
["TLS.expire"] = expireSeconds,
|
||
["TLS.time"] = now
|
||
};
|
||
|
||
var contentToSign = $"TLS.identifier:{userId}\nTLS.sdkappid:{_sdkAppId}\nTLS.time:{now}\nTLS.expire:{expireSeconds}\n";
|
||
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_secretKey));
|
||
var sig = hmac.ComputeHash(Encoding.UTF8.GetBytes(contentToSign));
|
||
obj["TLS.sig"] = Convert.ToBase64String(sig);
|
||
|
||
var jsonBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(obj));
|
||
|
||
// zlib 压缩
|
||
using var output = new MemoryStream();
|
||
using (var zlib = new System.IO.Compression.ZLibStream(output, System.IO.Compression.CompressionLevel.Optimal))
|
||
{
|
||
zlib.Write(jsonBytes, 0, jsonBytes.Length);
|
||
}
|
||
|
||
// Base64 URL 安全编码
|
||
return Convert.ToBase64String(output.ToArray())
|
||
.Replace('+', '*')
|
||
.Replace('/', '-')
|
||
.Replace('=', '_');
|
||
}
|
||
}
|