官方给出的顺序如下:
- 获取 POST 请求体 body 内容,序列化为计算签名使用的 payload
- 获取请求参数中的nonce和timestamp
- 将 payload 与签名密钥 secret 按照 “<nonce>:<payload>:<secret>:<timestamp>” 的形式组合为校验字符串 content
- 以 utf-8 编码形式计算 content 的 sha-1 散列
- 将 content 散列的十六进制字符串与 POST 请求 header 中的 ‘X-JDY-Signature’ 做比较
- 若比较结果相同,则通过签名验证;若比较结果不同,则无法通过检查
由于个人工程的需要我这里只展示新增状态如何推送数据:
1.验证函数,该函数主要用来和简道云完成身份的验证,判断是否为恶意访问
func getSignature(nonce string, payload string, key string, timestamp string) string {
signStr := []byte(nonce + ":" + payload + ":" + key + ":" + timestamp)
sha1Bytes := sha1.Sum(signStr)
return hex.EncodeToString(sha1Bytes[:])
}
2.选择函数,根据简道云给出的示例数据结构中有一个op,op对应的值就是操作,该函数将其解析出来选择对应的函数执行。
func handleData(payload map[string]interface{}) {
if payload["op"] == "data_create" {
if data, ok := payload["data"].(map[string]interface{}); ok {
order := processOrder(data)
add(order)
}
}
}
3.数据解析函数,该函数用来解析简道云发送的数据
func processOrder(data map[string]interface{}) Order {
order := Order{
Name: getString(data, "name"),
PhoneNumber: getString(data, "phone_number"),
Post: getString(data, "post"),
Title: getString(data, "title"),
Opinion: getString(data, "opinion"),
View: getString(data, "view"),
Reply: getString(data, "reply"),
}
order.SubmissionTime = parseTime(getString(data, "submission_time"))
order.RecoveryTime = parseTime(getString(data, "recovery_time"))
if mainDepartData, ok := data["main_depart"].([]interface{}); ok {
for _, dept := range mainDepartData {
if deptMap, ok := dept.(map[string]interface{}); ok {
mainDepart := MainDepart{
Name: getString(deptMap, "name"),
Username: getString(deptMap, "username"),
Status: getInt(deptMap, "status"),
Type: getInt(deptMap, "type"),
}
order.MainDepart = append(order.MainDepart, mainDepart)
}
}
}
return order
}
4.添加方法函数,该函数用于表单执行创建新增数据时,将数据插入到数据库中
func add(order Order) {
jsonData, err := json.Marshal(order)
if err != nil {
log.Printf("推送数据解码失败: %v", err)
return
}
code := generateRandomString()
token := generateRandomString()
_, err = database.GetDB().Exec(`
INSERT INTO data_import
(code, token, create_time, update_time, is_delete, create_user_code, ext_json, exp_json)
VALUES (?, ?, NOW(), NOW(), 0, NULL, ?, NULL)
`, code, token, string(jsonData))
if err != nil {
log.Printf("插入数据库失败: %v", err)
}
}