59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
import crypto from 'crypto';
|
||
|
||
export interface WechatEncryptBuilderOptions {
|
||
/** 预设的token,在微信公众平台/服务号后台配置 */
|
||
token: string;
|
||
/** 时间戳,使用Date.now()即可 */
|
||
timestamp: string;
|
||
/** 随机数,复用微信服务器传递的nonce参数 */
|
||
nonce: string;
|
||
}
|
||
|
||
/**
|
||
* 微信加密消息构建器
|
||
*
|
||
* 构建复合微信加密消息格式XML字符串,用于回包给微信服务器
|
||
*
|
||
* - 对应微信官方XML加密消息结构
|
||
* @see 微信官方文档: [消息加解密说明](https://developers.weixin.qq.com/doc/service/guide/dev/push/encryption.html)
|
||
*/
|
||
export class WechatEncryptBuilder {
|
||
/** 预设的token,在微信公众平台/服务号后台配置 */
|
||
private token: string;
|
||
/** 时间戳,使用Date.now()即可 */
|
||
private timestamp: string;
|
||
/** 随机数,复用微信服务器传递的nonce参数 */
|
||
private nonce: string;
|
||
|
||
constructor(options: WechatEncryptBuilderOptions) {
|
||
const {
|
||
token,
|
||
timestamp,
|
||
nonce,
|
||
} = options;
|
||
|
||
this.token = token;
|
||
this.timestamp = timestamp;
|
||
this.nonce = nonce;
|
||
}
|
||
|
||
/**
|
||
* 构建微信加密消息XML Response字符串
|
||
*
|
||
* @param encrypt 加密后的消息体(Base64编码的字符串)
|
||
* @returns 带有加密消息的XML Response字符串
|
||
*/
|
||
buildResponse(encrypt: string): string {
|
||
const tempArray = [this.token, this.timestamp, this.nonce, encrypt].sort();
|
||
const msgSig = crypto.createHash('sha1').update(tempArray.join('')).digest('hex');
|
||
|
||
const responseXml = `<xml>
|
||
<Encrypt><![CDATA[${encrypt}]]></Encrypt>
|
||
<MsgSignature><![CDATA[${msgSig}]]></MsgSignature>
|
||
<TimeStamp>${this.timestamp}</TimeStamp>
|
||
<Nonce><![CDATA[${this.nonce}]]></Nonce>
|
||
</xml>`;
|
||
|
||
return responseXml;
|
||
}
|
||
} |