事件推送是指火山引擎内容定制服务调用客户提供的接口,推送变更事件。
客户侧通过检验 signature 对请求进行校验(下面有校验方式),以确认请求来自内容定制系统。
参数 | 描述 |
---|---|
timestamp | unix时间戳,单位:秒。为保证安全,与当前时间戳绝对值不要超过3600s。 |
nonce | 请求随机串。随机串长度为6-32位数字和字母的组合,大小写敏感。 |
signature | 签名字符串。 |
payload | 业务数据。请求体body字节流。 |
secret_key | 鉴权密钥。客户侧可以在内容定制平台的【内容同步】页面,点击【同步配置】的【回调配置】查看。 |
Hmac_SHA256算法
将 timestamp、nonce 和 payload 依次进行拼接;
使用 secret_key 对上述拼接的字符串进行 hmac sha256 加密,然后转成十六进制字符串 ;
得到加密后的字符串可与 signature 对比,标识该请求来源于内容定制的内容事件推送。
检验signature的Java示例代码:
public static String genSignature(String timestamp, String nonce, String body, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException { // 按照 timestamp,nonce,body 顺序拼接签名字符串 String signatureStr = timestamp + nonce + body; // 进行 hmac sha256 加密 Mac hmacSha256 = hmacSha256 = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); hmacSha256.init(secretKeySpec); byte[] signatureBytes = hmacSha256.doFinal(signatureStr.getBytes(StandardCharsets.UTF_8)); // 将 sha256 字节数组转成16进制字符串 StringBuilder signatureBuilder = new StringBuilder(); for (byte signatureByte : signatureBytes) { String hex = Integer.toHexString(signatureByte & 0xFF); if (hex.length() == 1) { signatureBuilder.append('0'); } signatureBuilder.append(hex); } return signatureBuilder.toString(); }
检验signature的Go示例代码:
func GenSignature(timestamp, nonce, body, secretKey string) string { // 按照 timestamp,nonce,body 顺序拼接签名字符串 signatureStr := timestamp + nonce + body // 进行 hmac sha256 加密 hmacSha256 := hmac.New(sha256.New, []byte(secretKey)) hmacSha256.Write([]byte(signatureStr)) // 将 sha256 字节数组转成16进制字符串 signature := fmt.Sprintf("%x", hmacSha256.Sum(nil)) return signature }
请求方指“火山引擎-内容定制”。
KEY | VALUE/说明 |
---|---|
Method | POST |
Content-Type | application/json |
X-Content-Timestamp | unix时间戳(单位:秒) |
X-Content-Nonce | 随机串(6-32位数字、字母组成) |
X-Content-Signature | 回调签名(生成逻辑见上文) |
事件结构见事件章节
事件具体枚举件POI事件和内容事件部分
响应方指“客户侧”。
字段名 | 字段类型 | 说明 |
---|---|---|
ret | number | 响应状态码。0-成功;非0-失败,并在msg中补充说明。 |
msg | string | 响应信息。例如:成功时提供"success";失败时提供失败相关信息。 |
POST / HTTP/1.1 Host: xxx.xxx.xxx Content-Type: application/json X-Content-Timestamp: 1690366367 X-Content-Nonce: kfcv50 X-Content-Signature: 2d3891cee3dcc777ba27a29f70758c581e93f21f3dad1deeaadf11aa440fe4b2 Body: ${参考事件章节中的事件结构部分}
注意: 这里的Body应该作为一个字符串接收。不要利用引入的SDK或者框架的能力作为一个JSONObject接收,再转为字符串,这样可能导致Body的字符串内容不一致,从而导致签名计算出来的最终结果不一致。
客户侧服务端返回给火山引擎侧的响应数据
{ "ret": 0, // 响应状态码 "msg": "success" // 响应信息 }
[{ "Product": "interest_map", // 业务线,本场景中统一为interest_map "EventId": "7339149900963496457", // 事件唯一ID "EventType": "poi_created", // 事件类型 "EntityType": "poi", // 事件主体 "EntityId": "7339149900963496450", // 事件主体ID "EventTimeMillisec": "1708940969000", // 事件产生时间 "EventData": "" // 事件数据,经过序列化后的事件结构体,不同事件类型下不同 }]
领域 | 事件 | 事件结构说明 | 备注 |
---|---|---|---|
POI | POI新增 |
|
|
POI变更 |
|
| |
POI移除 |
|
|