用 .NET Core 生成微信JS-SDK需要的签名

在使用微信的 JS-SDK 进行微信公众号开发或是企业微信开发时,首先需要通过服务端程序去生成对应于前端每个页面的签名。 本文演示如何在 .NET Core 3.1 以上版本中生成该签名。

获取企业通讯的Token

要生成 JS-SDK 的签名,首先需要通过微信服务端API获取对应的通讯 JS Ticket, 而要获取 JS Ticket, 必须先获取与企业API访问相关的 Token。

为获取 Token , 我们使用微信服务端API, URL 为(可参考):

1
https://qyapi.weixin.qq.com/cgi-bin/gettoken

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private async Task<CropToken> getWxToken(string corpId, string secret)
{

using (HttpClient client = new HttpClient())
{
string url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
url += "?corpid=" + corpId;
url += "&corpsecret=" + secret;


HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();

string responseBody = await response.Content.ReadAsStringAsync();

var res = JsonSerializer.Deserialize<WxApiGetToken>(responseBody);

using (var db = new WxContext())
{
CropToken cropToken = db.CropTokens.SingleOrDefault<CropToken>(t => t.CorpId == this.corpId);
if (cropToken != null)
{
cropToken.AccessToken = res.accessToken;
cropToken.ExpiresIn = res.expiresIn;
cropToken.LastUpdateTime = new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds();
db.CropTokens.Update(cropToken);
}
else
{
cropToken = new CropToken();
cropToken.CorpId = corpId;
cropToken.AppSecret = secret;
cropToken.AccessToken = res.accessToken;
cropToken.ExpiresIn = res.expiresIn;
cropToken.LastUpdateTime = new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds();
db.CropTokens.Add(cropToken);
}

await db.SaveChangesAsync();
return cropToken;
}

}
}

注意: 在上面的代码中,为了避免频繁的访问微信服务端API, 我们将获取到的token 保存在本地数据库中

获取 JS Ticket

获取了 Token 以后,就可以用该 Token 继续获取 JS Ticket 了。 参考微信服务端API文档, 对应的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
private async Task<JsTicket> GetJsTicket()
{

using (HttpClient client = new HttpClient())
{

using (var db = new WxContext())
{

CropToken cropToken = db.CropTokens.SingleOrDefault<CropToken>(t => t.CorpId == this.corpId);

if (cropToken == null)
{

cropToken = await getWxToken(this.corpId, this.secret);
}

string url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket";
url += "?access_token=" + cropToken.AccessToken;

HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();

string responseBody = await response.Content.ReadAsStringAsync();

var res = JsonSerializer.Deserialize<WxApiJsTicket>(responseBody);

JsTicket jsTicket = new JsTicket();
jsTicket.CorpId = this.corpId;
jsTicket.Ticket = res.ticket;
jsTicket.ExpiresIn = res.expiresIn;
jsTicket.LastUpdateTime = new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds();

db.JsTickets.Add(jsTicket);

await db.SaveChangesAsync();

return jsTicket;

}
}
}

生成 JS-SDK 需要的签名

因为 JS-SDK 签名是针对前端的每个页面的,因此需要前端将当前页面的 URL 作为参数传到后端,后端的示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[HttpGet("enable")]
public async Task<ApiResult> enableJsSDK()
{
string url = Request.Query["url"];

_logger.LogDebug("enableJsSDK, url = {0}", url);

long timestamp = (new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()) / 1000;
string noncestr = getRandomStr();
string jsapiTicket = (await GetJsTicket()).Ticket;
string signature = SHA1_Hash("jsapi_ticket=" + jsapiTicket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url);

ApiResult result = new ApiResult();
result.Succ = true;

ConfigVo config = new ConfigVo();
config.Timestamp = timestamp;
config.NonceStr = noncestr;
config.Signature = signature;
config.AppId = this.corpId;

result.Data = config;

return result;
}

返回的数据为前端在页面上配置 js-sdk 时需要的信息。

其中分别调用生成随机串和生成 SHA1 加密串的程序,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private string getRandomStr() {

Random rnd = new Random();
string res = "";
for (int i = 0; i < 16; i++) {
res += RANDOM_STR.ElementAt(rnd.Next(RANDOM_STR.Length));
}

return res;
}


//SHA1哈希加密算法
public string SHA1_Hash(string str_sha1_in)
{
SHA1 sha1 = new SHA1CryptoServiceProvider();
byte[] bytes_sha1_in = System.Text.UTF8Encoding.Default.GetBytes(str_sha1_in);
byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in);
string str_sha1_out = BitConverter.ToString(bytes_sha1_out);
str_sha1_out = str_sha1_out.Replace("-", "").ToLower();
return str_sha1_out;
}

本文标题:用 .NET Core 生成微信JS-SDK需要的签名

文章作者:Morning Star

发布时间:2020年04月21日 - 14:04

最后更新:2021年04月16日 - 15:04

原始链接:https://www.mls-tech.info/dotnet/dotnet-core-js-sdk-config/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。